Php 将内爆阵列加载到$wpdb prepare失败 更新1
似乎$addressbits内爆存在问题。我手动添加了两个变量,然后用其中一个进行搜索以确保它不起作用,结果失败了,然后输入了两个值,搜索成功了 更新2 经过更多的测试,我发现prepare函数消除了第二次内爆,如果它在数组中有多个项,我不确定这是否是一个bug,但它确实很烦人。我正在研究在数组创建函数中运行prepare函数以进行清理,然后将其打印到查询中 我正在wordpress网站上构建一个自定义表的搜索表单。我试图将多个术语从文本字段传递到一个数组,然后将它们传递到$wpdb->prepare()中进行清理。到目前为止,我的代码只适用于一个术语。。。但如果我再加上一秒钟,它就不起作用了,就好像没有为字段输入任何术语一样。我最初认为后面的逗号可能会有问题,但在trim中添加代码不起作用,我甚至用逗号连接以确保它们的存在,然后用rtrim()进行修剪,仍然不起作用。我还添加了逗号而不是trim,但仍然无法使用多个术语。我已打开错误报告,没有显示任何内容Php 将内爆阵列加载到$wpdb prepare失败 更新1,php,wordpress,Php,Wordpress,似乎$addressbits内爆存在问题。我手动添加了两个变量,然后用其中一个进行搜索以确保它不起作用,结果失败了,然后输入了两个值,搜索成功了 更新2 经过更多的测试,我发现prepare函数消除了第二次内爆,如果它在数组中有多个项,我不确定这是否是一个bug,但它确实很烦人。我正在研究在数组创建函数中运行prepare函数以进行清理,然后将其打印到查询中 我正在wordpress网站上构建一个自定义表的搜索表单。我试图将多个术语从文本字段传递到一个数组,然后将它们传递到$wpdb->prep
#explode search field values
$addressinput = explode(" ", $_GET['address']);
#create inputs for prepare
$addressbits = array();
foreach ($addressinput as $input) {
$input = trim($input);
if (!empty($input)) {
$addressbits[] = $input ;
}
}
#create prepare statements
$addressclean = array();
foreach ($addressinput as $clean) {
$clean = trim($clean);
if (!empty($clean)) {
$addressclean[] = " and `display-address` LIKE '%%%s%%'";
}
}
#if field is not empty, build and execute prepare statement, set variable
if (isset($_GET['address'])) {
$displayaddress = $wpdb->prepare( implode( $addressclean ) , implode(',' , $addressbits));
} else {
$displayaddress = '';
}
#query with pagination code
$customPagHTML = "";
$query = "select * from `record-display` where" . $code . $displayaddress . $format . $name . " ORDER BY `date` DESC";
$total_query = "SELECT COUNT(1) FROM (${query}) AS combined_table";
$total = $wpdb->get_var( $total_query );
$items_per_page = 10;
$page = isset( $_GET['cpage'] ) ? abs( (int) $_GET['cpage'] ) : 1;
$offset = ( $page * $items_per_page ) - $items_per_page;
$result = $wpdb->get_results( $query . " LIMIT ${offset}, ${items_per_page}", ARRAY_A );
$totalPage = ceil($total / $items_per_page);
所以你似乎有一些问题 首先,如果没有
$\u GET['address']
,那么让所有用于组装的代码都运行$adresclean
是没有意义的-这不会有什么不同(从性能角度来看),但是将其进一步向下移动到if(isset($\u GET['address']){/code>
第二件事是,您在几乎相同的数组上循环了两次。同样,这不是什么大问题,但除非您确实需要$addressbits
变量,否则只需做一个循环(即使您需要,您实际上仍然可以做一个循环,只需做$addressbits[]=$input;
)
第三件事是您正在使用$wpdb->prepare()
错误。它希望您将每个替换变量作为另一个参数传递给函数。相反,您将所有$addressbits
串联起来并作为单个变量传递,而串联$addressclean
需要将多个参数传递给$wpdb->prepare()
。
在foreach循环中,逃逸每个片段更容易。
如果您不想这样做,那么您可以像最初那样编写代码,只需更新这些行(它们是断章取义的,但您应该能够理解):
这将向所有$addressbits元素添加百分比,使其可以在类似于
语句的语句中使用。正如您所见,我们在$addressclean[]
中去掉了单引号和所有额外的百分比。
最后,我们使用call\u user\u func\u array()
将一个参数数组传递给$wpdb->prepare()
。请注意,它实际上接收单独的参数,而不是单个数组(如有必要,请参阅上的文档)
最后一件事是,您不需要运行一个完整的额外查询来获取结果总数。请改用SQL\u CALC\u FOUND\u ROWS
——尽管根据您的表结构,最好运行第二个查询(尝试这两种方法,看看哪一种运行得更快)
无论如何,这是我建议的代码版本。请注意,我只是根据post\u title
查询posts表来尝试的。我必须编写$code
、$format
和$name
,因为您的代码中没有包含它们
#if field is not empty, build and execute prepare statement, set variable
if ( isset( $_GET['address'] ) ) {
#explode search field values
$addressinput = explode( ' ', $_GET['address'] );
#create inputs for prepare
$addressclean = array();
foreach ( $addressinput as $input ) {
$input = trim( $input );
if ( ! empty( $input ) ) {
$addressclean[] = $wpdb->prepare( '`display-address` LIKE %s', '%' . $wpdb->esc_like( $input ) . '%' );
}
}
$displayaddress = $addressclean ? ' AND ( ' . implode( ' AND ', $addressclean ) . ' ) ' : '';
} else {
$displayaddress = '';
}
#query with pagination code
$items_per_page = 10;
$page = isset( $_GET['cpage'] ) ? absint( $_GET['cpage'] ) : 1;
$offset = ( $page * $items_per_page ) - $items_per_page;
$customPagHTML = "";
$query = "SELECT SQL_CALC_FOUND_ROWS * FROM `record-display`
WHERE $code
$displayaddress
$format
$name
GROUP BY {$wpdb->posts}.ID
ORDER BY `post_date` DESC
LIMIT {$offset}, {$items_per_page}";
$result = $wpdb->get_results( $query, ARRAY_A );
$total = $wpdb->get_var( "SELECT FOUND_ROWS()" );
$totalPage = ceil( $total / $items_per_page );
谢谢你的详细帖子!我昨晚很晚才意识到这一点,并得出了相同的结果。我想我刚刚通过wpdb prepare的所有标准问题示例获得了tunnel vision。感谢你对分页代码的额外建议,我还没有过多地研究它的性能方面。我的方法的唯一区别是昨晚每个人都在使用prepare,我使用了:$addressbits[]=”和显示地址
“$wpdb->prepare(“像%%s%%”,$input);@photocode太棒了!我用$wpdb
查看了如何摆脱LIKE语句,这只是个人喜欢使用esc\u LIKE()
-看起来更干净,但我想可能会更让人困惑:)
#if field is not empty, build and execute prepare statement, set variable
if ( isset( $_GET['address'] ) ) {
#explode search field values
$addressinput = explode( ' ', $_GET['address'] );
#create inputs for prepare
$addressclean = array();
foreach ( $addressinput as $input ) {
$input = trim( $input );
if ( ! empty( $input ) ) {
$addressclean[] = $wpdb->prepare( '`display-address` LIKE %s', '%' . $wpdb->esc_like( $input ) . '%' );
}
}
$displayaddress = $addressclean ? ' AND ( ' . implode( ' AND ', $addressclean ) . ' ) ' : '';
} else {
$displayaddress = '';
}
#query with pagination code
$items_per_page = 10;
$page = isset( $_GET['cpage'] ) ? absint( $_GET['cpage'] ) : 1;
$offset = ( $page * $items_per_page ) - $items_per_page;
$customPagHTML = "";
$query = "SELECT SQL_CALC_FOUND_ROWS * FROM `record-display`
WHERE $code
$displayaddress
$format
$name
GROUP BY {$wpdb->posts}.ID
ORDER BY `post_date` DESC
LIMIT {$offset}, {$items_per_page}";
$result = $wpdb->get_results( $query, ARRAY_A );
$total = $wpdb->get_var( "SELECT FOUND_ROWS()" );
$totalPage = ceil( $total / $items_per_page );