dbdelta ( $queries = '', $execute = true )
dbdelta: 这个函数用来更新数据库模式,以符合一个给定的SQL语句的结构。它被WordPress在插件和主题安装和更新时使用,以确保数据库模式与代码相匹配。
根据指定的SQL语句来修改数据库。
对于创建新的表和更新现有的表到一个新的结构很有用。
function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid global $wpdb; if ( in_array( $queries, array( '', 'all', 'blog', 'global', 'ms_global' ), true ) ) { $queries = wp_get_db_schema( $queries ); } // Separate individual queries into an array. if ( ! is_array( $queries ) ) { $queries = explode( ';', $queries ); $queries = array_filter( $queries ); } /** * Filters the dbDelta SQL queries. * * @since 3.3.0 * * @param string[] $queries An array of dbDelta SQL queries. */ $queries = apply_filters( 'dbdelta_queries', $queries ); $cqueries = array(); // Creation queries. $iqueries = array(); // Insertion queries. $for_update = array(); // Create a tablename index for an array ($cqueries) of queries. foreach ( $queries as $qry ) { if ( preg_match( '|CREATE TABLE ([^ ]*)|', $qry, $matches ) ) { $cqueries[ trim( $matches[1], '`' ) ] = $qry; $for_update[ $matches[1] ] = 'Created table ' . $matches[1]; } elseif ( preg_match( '|CREATE DATABASE ([^ ]*)|', $qry, $matches ) ) { array_unshift( $cqueries, $qry ); } elseif ( preg_match( '|INSERT INTO ([^ ]*)|', $qry, $matches ) ) { $iqueries[] = $qry; } elseif ( preg_match( '|UPDATE ([^ ]*)|', $qry, $matches ) ) { $iqueries[] = $qry; } else { // Unrecognized query type. } } /** * Filters the dbDelta SQL queries for creating tables and/or databases. * * Queries filterable via this hook contain "CREATE TABLE" or "CREATE DATABASE". * * @since 3.3.0 * * @param string[] $cqueries An array of dbDelta create SQL queries. */ $cqueries = apply_filters( 'dbdelta_create_queries', $cqueries ); /** * Filters the dbDelta SQL queries for inserting or updating. * * Queries filterable via this hook contain "INSERT INTO" or "UPDATE". * * @since 3.3.0 * * @param string[] $iqueries An array of dbDelta insert or update SQL queries. */ $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries ); $text_fields = array( 'tinytext', 'text', 'mediumtext', 'longtext' ); $blob_fields = array( 'tinyblob', 'blob', 'mediumblob', 'longblob' ); $int_fields = array( 'tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint' ); $global_tables = $wpdb->tables( 'global' ); $db_version = $wpdb->db_version(); $db_server_info = $wpdb->db_server_info(); foreach ( $cqueries as $table => $qry ) { // Upgrade global tables only for the main site. Don't upgrade at all if conditions are not optimal. if ( in_array( $table, $global_tables, true ) && ! wp_should_upgrade_global_tables() ) { unset( $cqueries[ $table ], $for_update[ $table ] ); continue; } // Fetch the table column structure from the database. $suppress = $wpdb->suppress_errors(); $tablefields = $wpdb->get_results( "DESCRIBE {$table};" ); $wpdb->suppress_errors( $suppress ); if ( ! $tablefields ) { continue; } // Clear the field and index arrays. $cfields = array(); $indices = array(); $indices_without_subparts = array(); // Get all of the field names in the query from between the parentheses. preg_match( '|((.*))|ms', $qry, $match2 ); $qryline = trim( $match2[1] ); // Separate field lines into an array. $flds = explode( "n", $qryline ); // For every field line specified in the query. foreach ( $flds as $fld ) { $fld = trim( $fld, " tnrx0B," ); // Default trim characters, plus ','. // Extract the field name. preg_match( '|^([^ ]*)|', $fld, $fvals ); $fieldname = trim( $fvals[1], '`' ); $fieldname_lowercased = strtolower( $fieldname ); // Verify the found field name. $validfield = true; switch ( $fieldname_lowercased ) { case '': case 'primary': case 'index': case 'fulltext': case 'unique': case 'key': case 'spatial': $validfield = false; /* * Normalize the index definition. * * This is done so the definition can be compared against the result of a * `SHOW INDEX FROM $table_name` query which returns the current table * index information. */ // Extract type, name and columns from the definition. // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation preg_match( '/^' . '(?P<index_type>' // 1) Type of the index. . 'PRIMARYs+KEY|(?:UNIQUE|FULLTEXT|SPATIAL)s+(?:KEY|INDEX)|KEY|INDEX' . ')' . 's+' // Followed by at least one white space character. . '(?:' // Name of the index. Optional if type is PRIMARY KEY. . '`?' // Name can be escaped with a backtick. . '(?P<index_name>' // 2) Name of the index. . '(?:[0-9a-zA-Z$_-]|[xC2-xDF][x80-xBF])+' . ')' . '`?' // Name can be escaped with a backtick. . 's+' // Followed by at least one white space character. . ')*' . '(' // Opening bracket for the columns. . '(?P<index_columns>' . '.+?' // 3) Column names, index prefixes, and orders. . ')' . ')' // Closing bracket for the columns. . '$/im', $fld, $index_matches ); // phpcs:enable // Uppercase the index type and normalize space characters. $index_type = strtoupper( preg_replace( '/s+/', ' ', trim( $index_matches['index_type'] ) ) ); // 'INDEX' is a synonym for 'KEY', standardize on 'KEY'. $index_type = str_replace( 'INDEX', 'KEY', $index_type ); // Escape the index name with backticks. An index for a primary key has no name. $index_name = ( 'PRIMARY KEY' === $index_type ) ? '' : '`' . strtolower( $index_matches['index_name'] ) . '`'; // Parse the columns. Multiple columns are separated by a comma. $index_columns = array_map( 'trim', explode( ',', $index_matches['index_columns'] ) ); $index_columns_without_subparts = $index_columns; // Normalize columns. foreach ( $index_columns as $id => &$index_column ) { // Extract column name and number of indexed characters (sub_part). // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation preg_match( '/' . '`?' // Name can be escaped with a backtick. . '(?P<column_name>' // 1) Name of the column. . '(?:[0-9a-zA-Z$_-]|[xC2-xDF][x80-xBF])+' . ')' . '`?' // Name can be escaped with a backtick. . '(?:' // Optional sub part. . 's*' // Optional white space character between name and opening bracket. . '(' // Opening bracket for the sub part. . 's*' // Optional white space character after opening bracket. . '(?P<sub_part>' . 'd+' // 2) Number of indexed characters. . ')' . 's*' // Optional white space character before closing bracket. . ')' // Closing bracket for the sub part. . ')?' . '/', $index_column, $index_column_matches ); // phpcs:enable // Escape the column name with backticks. $index_column = '`' . $index_column_matches['column_name'] . '`'; // We don't need to add the subpart to $index_columns_without_subparts $index_columns_without_subparts[ $id ] = $index_column; // Append the optional sup part with the number of indexed characters. if ( isset( $index_column_matches['sub_part'] ) ) { $index_column .= '(' . $index_column_matches['sub_part'] . ')'; } } // Build the normalized index definition and add it to the list of indices. $indices[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns ) . ')'; $indices_without_subparts[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns_without_subparts ) . ')'; // Destroy no longer needed variables. unset( $index_column, $index_column_matches, $index_matches, $index_type, $index_name, $index_columns, $index_columns_without_subparts ); break; } // If it's a valid field, add it to the field array. if ( $validfield ) { $cfields[ $fieldname_lowercased ] = $fld; } } // For every field in the table. foreach ( $tablefields as $tablefield ) { $tablefield_field_lowercased = strtolower( $tablefield->Field ); $tablefield_type_lowercased = strtolower( $tablefield->Type ); $tablefield_type_without_parentheses = preg_replace( '/' . '(.+)' // Field type, e.g. `int`. . '(d*)' // Display width. . '(.*)' // Optional attributes, e.g. `unsigned`. . '/', '$1$2', $tablefield_type_lowercased ); // Get the type without attributes, e.g. `int`. $tablefield_type_base = strtok( $tablefield_type_without_parentheses, ' ' ); // If the table field exists in the field array... if ( array_key_exists( $tablefield_field_lowercased, $cfields ) ) { // Get the field type from the query. preg_match( '|`?' . $tablefield->Field . '`? ([^ ]*( unsigned)?)|i', $cfields[ $tablefield_field_lowercased ], $matches ); $fieldtype = $matches[1]; $fieldtype_lowercased = strtolower( $fieldtype ); $fieldtype_without_parentheses = preg_replace( '/' . '(.+)' // Field type, e.g. `int`. . '(d*)' // Display width. . '(.*)' // Optional attributes, e.g. `unsigned`. . '/', '$1$2', $fieldtype_lowercased ); // Get the type without attributes, e.g. `int`. $fieldtype_base = strtok( $fieldtype_without_parentheses, ' ' ); // Is actual field type different from the field type in query? if ( $tablefield->Type != $fieldtype ) { $do_change = true; if ( in_array( $fieldtype_lowercased, $text_fields, true ) && in_array( $tablefield_type_lowercased, $text_fields, true ) ) { if ( array_search( $fieldtype_lowercased, $text_fields, true ) < array_search( $tablefield_type_lowercased, $text_fields, true ) ) { $do_change = false; } } if ( in_array( $fieldtype_lowercased, $blob_fields, true ) && in_array( $tablefield_type_lowercased, $blob_fields, true ) ) { if ( array_search( $fieldtype_lowercased, $blob_fields, true ) < array_search( $tablefield_type_lowercased, $blob_fields, true ) ) { $do_change = false; } } if ( in_array( $fieldtype_base, $int_fields, true ) && in_array( $tablefield_type_base, $int_fields, true ) && $fieldtype_without_parentheses === $tablefield_type_without_parentheses ) { /* * MySQL 8.0.17 or later does not support display width for integer data types, * so if display width is the only difference, it can be safely ignored. * Note: This is specific to MySQL and does not affect MariaDB. */ if ( version_compare( $db_version, '8.0.17', '>=' ) && ! str_contains( $db_server_info, 'MariaDB' ) ) { $do_change = false; } } if ( $do_change ) { // Add a query to change the column type. $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN `{$tablefield->Field}` " . $cfields[ $tablefield_field_lowercased ]; $for_update[ $table . '.' . $tablefield->Field ] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}"; } } // Get the default value from the array. if ( preg_match( "| DEFAULT '(.*?)'|i", $cfields[ $tablefield_field_lowercased ], $matches ) ) { $default_value = $matches[1]; if ( $tablefield->Default != $default_value ) { // Add a query to change the column's default value $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN `{$tablefield->Field}` SET DEFAULT '{$default_value}'"; $for_update[ $table . '.' . $tablefield->Field ] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}"; } } // Remove the field from the array (so it's not added). unset( $cfields[ $tablefield_field_lowercased ] ); } else { // This field exists in the table, but not in the creation queries? } } // For every remaining field specified for the table. foreach ( $cfields as $fieldname => $fielddef ) { // Push a query line into $cqueries that adds the field to that table. $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef"; $for_update[ $table . '.' . $fieldname ] = 'Added column ' . $table . '.' . $fieldname; } // Index stuff goes here. Fetch the table index structure from the database. $tableindices = $wpdb->get_results( "SHOW INDEX FROM {$table};" ); if ( $tableindices ) { // Clear the index array. $index_ary = array(); // For every index in the table. foreach ( $tableindices as $tableindex ) { $keyname = strtolower( $tableindex->Key_name ); // Add the index to the index data array. $index_ary[ $keyname ]['columns'][] = array( 'fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part, ); $index_ary[ $keyname ]['unique'] = ( 0 == $tableindex->Non_unique ) ? true : false; $index_ary[ $keyname ]['index_type'] = $tableindex->Index_type; } // For each actual index in the index array. foreach ( $index_ary as $index_name => $index_data ) { // Build a create string to compare to the query. $index_string = ''; if ( 'primary' === $index_name ) { $index_string .= 'PRIMARY '; } elseif ( $index_data['unique'] ) { $index_string .= 'UNIQUE '; } if ( 'FULLTEXT' === strtoupper( $index_data['index_type'] ) ) { $index_string .= 'FULLTEXT '; } if ( 'SPATIAL' === strtoupper( $index_data['index_type'] ) ) { $index_string .= 'SPATIAL '; } $index_string .= 'KEY '; if ( 'primary' !== $index_name ) { $index_string .= '`' . $index_name . '`'; } $index_columns = ''; // For each column in the index. foreach ( $index_data['columns'] as $column_data ) { if ( '' !== $index_columns ) { $index_columns .= ','; } // Add the field to the column list string. $index_columns .= '`' . $column_data['fieldname'] . '`'; } // Add the column list to the index create string. $index_string .= " ($index_columns)"; // Check if the index definition exists, ignoring subparts. $aindex = array_search( $index_string, $indices_without_subparts, true ); if ( false !== $aindex ) { // If the index already exists (even with different subparts), we don't need to create it. unset( $indices_without_subparts[ $aindex ] ); unset( $indices[ $aindex ] ); } } } // For every remaining index specified for the table. foreach ( (array) $indices as $index ) { // Push a query line into $cqueries that adds the index to that table. $cqueries[] = "ALTER TABLE {$table} ADD $index"; $for_update[] = 'Added index ' . $table . ' ' . $index; } // Remove the original table creation query from processing. unset( $cqueries[ $table ], $for_update[ $table ] ); } $allqueries = array_merge( $cqueries, $iqueries ); if ( $execute ) { foreach ( $allqueries as $query ) { $wpdb->query( $query ); } } return $for_update; }
要使用` get_users
`函数获取所有用户列表,可以按照以下步骤进行:
1. 使用` get_users
`函数调用获取用户列表:
$users = get_users();
2. 您可以按需使用参数来过滤结果。例如,您可以通过角色、用户ID、用户登录名等过滤用户列表。以下是一个根据用户角色为过滤条件的示例:
$users = get_users( array( 'role' => 'subscriber' // 将角色名称替换为您要过滤的角色 ) );
在上述示例中,将` role
`参数设置为所需的角色名称来过滤用户列表。
3. 您可以使用循环遍历获取的用户列表,并访问每个用户的属性。例如,以下示例将显示每个用户的用户名和电子邮件地址:
foreach( $users as $user ) { echo '用户名:' . $user->user_login . ', 电子邮件:' . $user->user_email . ; }
在上述示例中,通过` $user->user_login
`和` $user->user_email
`访问每个用户的用户名和电子邮件地址。
请注意,` get_users
`函数默认返回所有用户,并可以根据需要使用更多参数进行过滤。您可以参阅WordPress官方文档中的` get_users
`函数文档,了解更多可用参数和用法示例。
总结起来,使用` get_users
`函数获取所有用户列表的步骤是:
get_users
`函数获取用户列表。在WordPress中,可以使用WP_PLUGIN_DIR和WP_PLUGIN_URL常量来定义插件的目录路径和URL。
1. `WP_PLUGIN_DIR`:这是一个常量,用于定义插件的目录路径(文件系统路径)。您可以使用以下代码在插件文件中访问该常量:
$plugin_dir = WP_PLUGIN_DIR . '/your-plugin-folder/';
在上述代码中,将"your-plugin-folder"替换为您插件的实际文件夹名称。使用该常量,您可以获取插件文件的完整路径。
2. `WP_PLUGIN_URL`:这是一个常量,用于定义插件的URL(用于在网页上访问插件文件)。以下是一个使用该常量的示例:
$plugin_url = WP_PLUGIN_URL . '/your-plugin-folder/';
同样,请将"your-plugin-folder"替换为您插件的实际文件夹名称。使用该常量,您可以获取插件在网页上的完整URL。
请注意,`WP_PLUGIN_DIR`和`WP_PLUGIN_URL`常量在WordPress版本2.6之后引入。从WordPress 5.5版本开始,这两个常量被标记为过时(deprecated),因为WordPress更倾向于使用新的插件文件结构。如果您正在开发新插件,建议使用新的插件文件结构和相关函数。
在新的插件文件结构中,可以使用以下函数来获取插件的目录路径和URL:
- `plugin_dir_path()`:获取插件目录路径。
- `plugin_dir_url()`:获取插件URL。
这些函数会自动将插件的版本、多站点和SSL等考虑因素纳入计算。
总结起来,使用`WP_PLUGIN_DIR`和`WP_PLUGIN_URL`常量定义插件的目录和URL的方法是:
$plugin_dir = WP_PLUGIN_DIR . '/your-plugin-folder/'; $plugin_url = WP_PLUGIN_URL . '/your-plugin-folder/';
但请注意,这两个常量已被标记为过时,建议使用新的插件文件结构和相关函数来获取插件的路径和URL。
使用PHP在WordPress中添加自定义功能可以通过以下方式实现:
下面是一个实操示例。
要在WordPress中添加自定义功能,可以按照以下步骤使用PHP编写并添加自定义功能:
// 添加自定义功能示例 // 1. 创建自定义短代码 function custom_shortcode() { return '这是我的自定义短代码内容'; } add_shortcode('custom', 'custom_shortcode'); // 2. 自定义小工具 function custom_widget() { echo '这是我的自定义小工具内容'; } register_widget('custom_widget'); // 3. 自定义菜单 function custom_menu() { register_nav_menu('custom-menu', '自定义菜单'); } add_action('after_setup_theme', 'custom_menu'); // 4. 自定义页面模板 function custom_page_template() { /* Template Name: 自定义模板 */ // 自定义模板的内容和样式 }
请注意,修改主题文件可以在主题更新时丢失,因此建议在进行任何更改之前备份functions.php文件。此外,为避免不必要的错误和冲突,建议在添加自定义功能前先了解WordPress开发文档和最佳实践,以确保正确、安全地实现所需的自定义功能。
使用 do_action
函数可以触发一个钩子函数。do_action
函数的参数与要触发的钩子函数的参数相同。
例如,触发save_post钩子函数的代码如下:
do_action( 'save_post', $post_ID, $post );
这里,$post_ID
和 $post
是传递给钩子函数的参数。
使用 wp_get_current_user
获取当前登录用户的信息:
$current_user = wp_get_current_user(); // 获取当前用户的ID $user_id = $current_user->ID; // 获取当前用户的用户名 $user_login = $current_user->user_login; // 获取当前用户的邮箱 $user_email = $current_user->user_email; // 获取当前用户的显示名称 $display_name = $current_user->display_name;