在天才功能"准备" wpdb-class(在 includes / wp-dp.php 中)我无法解释为什么isset( $args[0] )
是必要的。
Alread clear是1 < func_num_args()
然后第一个条目被移位。它仍然是0 < func_num_args()
因此必须存在第一个条目。 $args[0]
可能是NULL
但是如果是这样的话,它就不能是一个数组,它会在同一个地方进行测试&#34; if&#34; if ( isset( $args[0] ) && is_array($args[0]) )
。
那么我错过了什么?
function prepare( $query, $args = null ) {
if ( is_null( $query ) )
return;
if ( func_num_args() < 2 )
_doing_it_wrong( 'wpdb::prepare', 'wpdb::prepare() requires at least two arguments.', '3.5' );
$args = func_get_args();
array_shift( $args );
// If args were passed as an array (as in vsprintf), move them up
if ( isset( $args[0] ) && is_array($args[0]) )
$args = $args[0];
$query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
$query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
$query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
$query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
array_walk( $args, array( $this, 'escape_by_ref' ) );
return @vsprintf( $query, $args );
}
答案 0 :(得分:0)
首先我不知道你得到这个代码的版本,但是在最后一个WP版本上没有func_num_args
检查 - 也许你从瞬态版本when they made this fix得到了这个代码。在WP 4.3.1中,prepare
函数看起来像这样:
public function prepare( $query, $args ) {
if ( is_null( $query ) )
return;
// This is not meant to be foolproof -- but it will catch obviously incorrect usage.
if ( strpos( $query, '%' ) === false ) {
_doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9' );
}
$args = func_get_args();
array_shift( $args );
// If args were passed as an array (as in vsprintf), move them up
if ( isset( $args[0] ) && is_array($args[0]) )
$args = $args[0];
$query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
$query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
$query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
$query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
array_walk( $args, array( $this, 'escape_by_ref' ) );
return @vsprintf( $query, $args );
}
所以让我们首先翻译代码:
if ( strpos( $query, '%' ) === false )
如果没有传递任何参数的查询,自定义错误处理程序将告诉用户他不应该使用prepare
进行此类查询。
$args = func_get_args();
非常简单,它将所有参数发送到函数。它将获得具有这种结构的数组:
Array(2) (
[0] => $query,
[1] => $args
)
然后就在:
array_shift( $args );
这将删除$args
($query
)的第一个值,因此我们最终会看到一个新的数组:
Array(2) (
[0] => $args
)
然后是嗡嗡叫你的测试:
if ( isset( $args[0] ) && is_array($args[0]) )
要理解isset
为什么是必要的,让我们假设您尝试像这样调用prepare
函数:
$wpdb->prepare("SELECT * FROM table WHERE arg1 = %s");
那个电话的结果是什么?该查询内部有%s
,因此它将被视为有效。我们将只获得一个带有查询的参数表,在它被移位之后,我们将获得一个空数组。然后,isset
将返回false
,因为0
索引不存在,和如果in_array
将被执行,它将显示以下内容错误(如果启用了通知错误显示):
Notice: Undefined offset: 0 in ***.php on line **
这是一个说明这一点的小脚本:
function test_args($arg1, $arg2) {
$args = func_get_args();
echo '<b>func_get_args : </b>';
var_dump($args);
array_shift($args);
echo '<b>array_shift : </b>';
var_dump($args);
echo '<b>isset($args[0]) : </b>';
var_dump(isset($args[0]));
echo '<b>is_array($args[0]) : </b>';
var_dump(is_array($args[0]));
echo '----<br />';
}
test_args('arg 1');
将输出以下内容:
func_get_args : array(1) {
[0]=>
string(5) "arg 1"
}
array_shift : array(0) {
}
isset($args[0]) : bool(false)
is_array($args[0]) :
Notice: Undefined offset: 0 in E:\www\test-args.php on line 17
为什么此isset
检查有效。 虽然,因为$args
不再是可选的,我们也会为prepare函数收到警告,因为我们只发送一个参数 - 这可能会在dev进程中丢失。我们错过了可选的$args
和func_num_args
检查 - 这两个以前的检查会使isset
检查失效,并防止显示任何错误。这可能应该在the WP bug report报告。