Php Wordpress插件表,无法使用dbDelta创建,尽管sql是正确的

Php Wordpress插件表,无法使用dbDelta创建,尽管sql是正确的,php,mysql,sql-server,wordpress,Php,Mysql,Sql Server,Wordpress,我正在尝试让我的Wordpress插件创建包含激活数据的表 SQL看起来是执行的,而且本身是正确的(事实上,如果我手动将其复制到SQL server,它就会工作) 我的PHP代码如下 register_activation_hook( __FILE__, function () { global $wpdb; $table_name = $wpdb->prefix . "ajax_preview_galleries"; $charset_collate = $wpdb->ge

我正在尝试让我的Wordpress插件创建包含激活数据的表

SQL看起来是执行的,而且本身是正确的(事实上,如果我手动将其复制到SQL server,它就会工作)

我的PHP代码如下

register_activation_hook( __FILE__, function () {
 global $wpdb;
 $table_name = $wpdb->prefix . "ajax_preview_galleries"; 
 $charset_collate = $wpdb->get_charset_collate();

 //Table definition
$sql =  "CREATE TABLE $table_name (
gallery_id int(10) unsigned NOT NULL AUTO_INCREMENT,
gallery_name varchar(100) COLLATE utf8_unicode_ci NOT NULL,
gallery_slug varchar(100) COLLATE utf8_unicode_ci NOT NULL,
gallery_selected_terms text COLLATE utf8_unicode_ci NOT NULL,
gallery_select_by tinyint(3) unsigned NOT NULL COMMENT '0: categories only; 1: tags only; 2: both',
gallery_post_count tinyint(3) unsigned NOT NULL,
gallery_custom_class_container varchar(200) COLLATE utf8_unicode_ci NOT NULL,
gallery_custom_class_buttons varchar(200) COLLATE utf8_unicode_ci NOT NULL,
gallery_transition_time int(10) unsigned NOT NULL DEFAULT '500',
gallery_loading_type tinyint(3) unsigned NOT NULL DEFAULT '1',
gallery_navigator_loop tinyint(3) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY  (gallery_id)
) $charset_collate;";

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );

$res = dbDelta($sql);
});
如果我输出
$res
,我会得到以下结果:
数组([orhub\u ajax\u preview\u galleries]=>创建的表或hub\u ajax\u preview\u galleries)

这说明一切都很好。但是,如果我检查数据库,表不在那里,插件确实无法存储数据

正如我所说,我试图输出
$sql
,并将其直接粘贴到phpMyAdmin中。这是有效的,所以问题似乎不在查询中

那么还有什么不对劲呢


顺便说一句,我也尝试了
可能创建\u表
,但也不起作用

在dbDelta之前添加以下内容:

require_once(ABSPATH.'wp admin/includes/upgrade.php')


您必须添加该行以显式加载运行dbDelta所需的核心部分。

好,因此您在
库中的
创建表
中的注释中有非法字符

尝试:

global $wpdb;
$table_name = $wpdb->prefix . "ajax_preview_galleries";
$charset_collate = $wpdb->get_charset_collate();

//Table definition
$sql =  "CREATE TABLE $table_name (
gallery_id int(10) unsigned NOT NULL AUTO_INCREMENT,
gallery_name varchar(100) COLLATE utf8_unicode_ci NOT NULL,
gallery_slug varchar(100) COLLATE utf8_unicode_ci NOT NULL,
gallery_selected_terms text COLLATE utf8_unicode_ci NOT NULL,
gallery_select_by tinyint(3) unsigned NOT NULL COMMENT '0 - categories only. 1 - tags only. 2 - both',
gallery_post_count tinyint(3) unsigned NOT NULL,
gallery_custom_class_container varchar(200) COLLATE utf8_unicode_ci NOT NULL,
gallery_custom_class_buttons varchar(200) COLLATE utf8_unicode_ci NOT NULL,
gallery_transition_time int(10) unsigned NOT NULL DEFAULT '500',
gallery_loading_type tinyint(3) unsigned NOT NULL DEFAULT '1',
gallery_navigator_loop tinyint(3) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY  (gallery_id)
) $charset_collate;";

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );

$res = dbDelta($sql);
问题是,你有
可能发出结束sql语句的信号,因此出现错误

我试图搜索转义它,但只找到了字符串文字,没有找到关于冒号和分号的内容

希望这有帮助。

成功了! 看起来,问题在于其中一个专栏的评论。事实上,我也这么怀疑,而且我已经尝试删除评论,尽管
gallery\u select\u by column
上的评论没有引起我的注意。感谢野狗把我的注意力指向那条线

但是,指定“dbDelta函数相当挑剔。例如:

  • 在SQL语句中,必须将每个字段放在自己的行上
  • 主键和主键定义之间必须有两个空格
  • 必须使用关键字key而不是其同义词索引,并且必须至少包含一个关键字
  • 不得在字段名周围使用任何撇号或反勾号。 字段类型必须全部为小写
  • SQL关键字,如CREATETABLE和UPDATE,必须是大写
  • 例如,必须指定接受长度参数.int(11)的所有字段的长度
看起来,这些只是一些例子,而dbDelta()甚至对评论也有一些抱怨。我无法找到dbDelta的“规则”的完整列表,但至少我找到了我的理由

顺便说一句:如前所述,在未创建表时,我通常从dbDelta()获取此结果

Result: Array ( [orhub_ajax_preview_galleries] => Created table orhub_ajax_preview_galleries ) 
现在插件工作了,取而代之的是,我得到了一个空数组! 这对我来说似乎很奇怪,因为它完全违反直觉(与dbDelta()的其他方面一样),所以知道这一点可能是件好事,我为可能与相同问题作斗争的其他人指出了这一点

在处理dbDelta()时,似乎必须考虑到“特殊规则”的适用性,并且在其他地方工作的查询在这里可能不起作用(事实上,正如我所提到的,我的原始sql在直接放入phpMyAdmin时起作用)。函数的结果也可能不是那么简单…

您可能想要尝试以下方法:


我从未有幸让dbDelta正常工作。我很好奇你是否能解决这个问题。我会的…但你现在吓坏我了..:DDo你确定你的PHP版本可以运行匿名函数吗?当你将它放入
注册激活钩子时,函数是否真的会启动,而它只是不创建表?是的,我知道我在其他地方没有函数,我也得到了DbDelta的输出(orhub_ajax_preview_galleries]=>Created table orhub_ajax_preview_galleries),所以…我只是在wp上对数据库做些事情,当我将你的代码粘贴到我的插件中时,我得到了以下错误:
WordPress数据库错误:[您的SQL语法有错误;请查看与您的MySQL服务器版本相对应的手册,以了解第6行“0:categories only”附近使用的正确语法]
是的,它在那里,但我在复制/粘贴时丢失了它。我编辑了答案,谢谢你的通知。是的,谢谢!我实际上已经尝试完全删除注释,但那一行没有引起我的注意。dbDelta()似乎是相当奇怪的工作。为了其他用户的缘故,我写了一个详细的答案在这里,希望它将节省一些头痛别人!
$table_name = "ratings";

$table_columns = "id INT(6) UNSIGNED AUTO_INCREMENT,
                    rate tinyint(1) NOT NULL,
                    ticket_id bigint(20) NOT NULL,
                    response_id bigint(20) NOT NULL,
                    created_at TIMESTAMP";

$table_keys = "PRIMARY KEY (id),
                    KEY ratings_rate (rate),
                    UNIQUE KEY ratings_response_id (response_id)";

create_table($table_name, $table_columns, $table_keys);

/**
 * Prevents unnecessary re-creating index and repetitive altering table operations when using WordPress dbDelta function
 *
 * Usage Example:
 *
 * $table_name      = "ratings";
 *
 * $table_columns   = "id INT(6) UNSIGNED AUTO_INCREMENT,
 *          rate tinyint(1) NOT NULL,
 *          ticket_id bigint(20) NOT NULL,
 *          response_id bigint(20) NOT NULL,
 *          created_at TIMESTAMP";
 *
 * $table_keys      = "PRIMARY KEY (id),
 *          KEY ratings_rate (rate),
 *          UNIQUE KEY ratings_response_id (response_id)";
 *
 * create_table($table_name, $table_columns, $table_keys);
 *
 * Things that need to be considered when using dbDelta function :
 *
 * You must put each field on its own line in your SQL statement.
 * You must have two spaces between the words PRIMARY KEY and the definition of your primary key.
 * You must use the key word KEY rather than its synonym INDEX and you must include at least one KEY.
 * You must not use any apostrophes or backticks around field names.
 * Field types must be all lowercase.
 * SQL keywords, like CREATE TABLE and UPDATE, must be uppercase.
 * You must specify the length of all fields that accept a length parameter. int(11), for example.
 *
 * Further information can be found on here:
 *
 * http://codex.wordpress.org/Creating_Tables_with_Plugins
 *
 * @param $table_name
 * @param $table_columns
 * @param null $table_keys
 * @param null $charset_collate
 * @version 1.0.1
 * @author Ugur Mirza Zeyrek
 */
function create_table($table_name, $table_columns, $table_keys = null, $db_prefix = true, $charset_collate = null) {
    global $wpdb;

    if($charset_collate == null)
        $charset_collate = $wpdb->get_charset_collate();
    $table_name = ($db_prefix) ? $wpdb->prefix.$table_name : $table_name;
    $table_columns = strtolower($table_columns);

    if($table_keys)
        $table_keys =  ", $table_keys";

    $table_structure = "( $table_columns $table_keys )";

    $search_array = array();
    $replace_array = array();

    $search_array[] = "`";
    $replace_array[] = "";

    $table_structure = str_replace($search_array,$replace_array,$table_structure);

    $sql = "CREATE TABLE $table_name $table_structure $charset_collate;";

    // Rather than executing an SQL query directly, we'll use the dbDelta function in wp-admin/includes/upgrade.php (we'll have to load this file, as it is not loaded by default)
    require_once (ABSPATH . 'wp-admin/includes/upgrade.php');

    // The dbDelta function examines the current table structure, compares it to the desired table structure, and either adds or modifies the table as necessary
    return dbDelta($sql);
}