Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php mysqli bind_param中可变长度参数列表的最佳实践_Php_Mysqli_Prepared Statement_Variadic Functions - Fatal编程技术网

Php mysqli bind_param中可变长度参数列表的最佳实践

Php mysqli bind_param中可变长度参数列表的最佳实践,php,mysqli,prepared-statement,variadic-functions,Php,Mysqli,Prepared Statement,Variadic Functions,我正在寻找处理mysqlibind_param方法的可变长度参数的最佳方法/模式/习惯用法 我在PHP中创建了一个变量函数,类似于mysqli\u stmt::bind\u param。因此,第一个必需参数需要一个字符串,其他参数是可选的,但第一个参数的字符串长度必须等于可选参数的数量 函数定义: function bind_param_test($types, ...$args){ $typesArr = str_split($types); foreach($args as

我正在寻找处理mysqli
bind_param
方法的可变长度参数的最佳方法/模式/习惯用法

我在PHP中创建了一个变量函数,类似于
mysqli\u stmt::bind\u param
。因此,第一个必需参数需要一个字符串,其他参数是可选的,但第一个参数的字符串长度必须等于可选参数的数量

函数定义:

function bind_param_test($types, ...$args){
    $typesArr = str_split($types);

    foreach($args as $i => $n) {

        switch ($typesArr[$i]) {
            case 'd':
                echo "Decimal: " . $n . '<br>';
                break;
            case 's':
                echo "String: " . $n . '<br>';
                break;
            default:
                break;
        }
    }
}

问题是:你能找到比案例4更好的方法吗?我这么问是因为我觉得第四个案子很神秘。我担心这可能会让其他开发者大吃一惊

您可以减少处理所有所需类型的数组,并对不允许的类型抛出异常。更现代的PHP支持数组销毁
..$array
[$var1,$var2]=$array

当我传递一个
$actionStr='xyz'
时,您还应该抛出一个异常

此示例根据您的订单
是数字的
是字符串
,它同时处理
'123'
123
,作为数字:

// ------------- CASE 4 ---------------------------

$argumentList = array(
  'a' => 'ten',
  'b' => 20,
  'c' => '0',
  'd' => null,
  'e' => 0,
//  'e' => false,   // throws Exception
//  'f' => [1,2,3], // throws Exception
);


[$argumentList, $actionStr] = array_reduce
(
  $argumentList,
  function(array $aggr, $v) : array
  {

    if(null === $v)
      return $aggr;

    if(is_numeric($v))
    {
      $aggr[0][] = $v;
      $aggr[1]  .= 'd';
      return $aggr;
    }

    if(is_string($v))
    {
      $aggr[0][] = $v;
      $aggr[1]  .= 's';
      return $aggr;
    }

    throw new InvalidArgumentException('Type ' . gettype($v) . ' not allowed.');

  },
  [[], '']
);

doSomething($actionStr, ...$argumentList);

如果希望将
'123'
处理为字符串而不是数字,请首先选中
是否为字符串。

我想回答我自己的问题。我只是想改进这个案子。 这是我的进步

$argumentList = array(
    'a' => 10,
    'b' => 20,
    'c' => null,
    'd' => null,
    'e' => null,
);

$argumentList = array_filter($argumentList);

$mysqli_param_types = '';
foreach($argumentList as $k => $v){

    if(is_numeric($v)){
        $actionStr .= 'd';
    }

    if(is_string($v)){
        $actionStr .= 's';
    }
}

// instead of array_values() and array_merge()
// its more clear to iterate over argumentList (even if its twice)
$mysqli_reference_params[] =& $actionStr;
foreach($argumentList as &$var) {
    $mysqli_reference_params[] =& $var;
}

call_user_func_array('bind_param_test',  $mysqli_reference_params);

/* OUTPUT:
Decimal: 10
Decimal: 20  */
好吧,为什么这很重要?这很重要,因为我希望有一个模式能够很好地与
bind_param
和可变长度参数列表配合使用

惯用语:mysqli中的可变长度准备语句

处理mysqli中可变长度参数列表并结合准备语句的习惯用法。 这里是一个真正的代码习惯用法

$sql = "    SELECT  p.`productID`,
                    p.`productCode`,
                    p.`productName`,
                    p.`productDescription`,
                    p.`productPrice`,
                    p.`productRating`,
                    p.`productDateTime`
            FROM `products` as p
            WHERE `p`.`productID` IS NOT NULL ";

        if($searchCode){
            $sql .= "AND p.`productCode` = ? ";
        }
        if($searchName){
            $sql .= "AND p.`productName` = ? ";
        }
        if($searchDescription) {
            $sql .= "AND p.`productDescription` = ? ";
        }
        if($searchPrice) {
            $sql .= "AND p.`productPrice` = ? ";
        }
        if($searchRating) {
            $sql .= "AND p.`productRating` = ? ";
        }
        if($searchDateTime) {
            $sql .= "AND p.`productDateTime` = ? ";
        }

        // Create mysqli_stmt
        $statement = $mysqli->prepare($sql);
        if ($statement instanceof \mysqli_stmt === false) {
            return null;
        }

        // Handle search variables through bind_param()
        $bindParamVarList = array(
            'productCode' => $searchCode,
            'productName' => $searchName,
            'productDescription' => $searchDescription,
            'productPrice' => $searchPrice,
            'productRating' => $searchRating,
            'productDateTime' => $searchDateTime,
        );
        $bindParamVarList = array_filter($bindParamVarList);

        if($bindParamVarList){
            $types = '';
            foreach($bindParamVarList as &$v){

                if(is_numeric($v)){
                    $types .= 'd';
                    $v = (float)$v;
                    continue;
                }

                if(is_string($v)){
                    $types .= 's';
                    continue;
                }
            }

            // call_user_func_array needs references and not values
            $mysqli_reference_params = array();
            $mysqli_reference_params[] =& $types;
            foreach($bindParamVarList as &$bindParamVar) {
                $mysqli_reference_params[] =& $bindParamVar;
            }

            call_user_func_array(array($statement,  'bind_param'),  $mysqli_reference_params);
        }

        $statement->execute();
        $statement->store_result();
        $amount = $statement->num_rows;

        $statement->bind_result($productID,
                                $productCode,
                                $productName,
                                $productDescription,
                                $productPrice,
                                $productRating,
                                $productDateTime
        );

        $products = array();
        $productsSet = array();
        while($statement->fetch()){
            $product = array();
            $product['productID'] = $productID;
            $product['productCode'] = $productCode;
            $product['productName'] = $productName;
            $product['productDescription'] = $productDescription;
            $product['productPrice'] = $productPrice;
            $product['productRating'] = $productRating;
            $product['productDateTime'] = $productDateTime;

            $products[] = $product;
        }

        // JavaScript is only able to work with indexed Array's
        $productsSet[] = $products;
        $productsSet[] = $amount;

您可以将最后5行缩减为
doSomething($actionStr,$argumentList)您打算如何使用
阵列过滤器
?不仅应该删除
null
,而且还应该删除
“”,0,'0',false,array()
。@Quasimodo's如果为null,则我不希望该项位于参数列表中。然后,您至少必须在回调函数中指定它。默认情况下,它可以过滤上面我的评论中列出的所有计算结果为false的内容。@Quasimodo's one-hmmmm我想知道在案例4中是否有改进的余地,而不是回调函数中。
// ------------- CASE 4 ---------------------------

$argumentList = array(
  'a' => 'ten',
  'b' => 20,
  'c' => '0',
  'd' => null,
  'e' => 0,
//  'e' => false,   // throws Exception
//  'f' => [1,2,3], // throws Exception
);


[$argumentList, $actionStr] = array_reduce
(
  $argumentList,
  function(array $aggr, $v) : array
  {

    if(null === $v)
      return $aggr;

    if(is_numeric($v))
    {
      $aggr[0][] = $v;
      $aggr[1]  .= 'd';
      return $aggr;
    }

    if(is_string($v))
    {
      $aggr[0][] = $v;
      $aggr[1]  .= 's';
      return $aggr;
    }

    throw new InvalidArgumentException('Type ' . gettype($v) . ' not allowed.');

  },
  [[], '']
);

doSomething($actionStr, ...$argumentList);
$argumentList = array(
    'a' => 10,
    'b' => 20,
    'c' => null,
    'd' => null,
    'e' => null,
);

$argumentList = array_filter($argumentList);

$mysqli_param_types = '';
foreach($argumentList as $k => $v){

    if(is_numeric($v)){
        $actionStr .= 'd';
    }

    if(is_string($v)){
        $actionStr .= 's';
    }
}

// instead of array_values() and array_merge()
// its more clear to iterate over argumentList (even if its twice)
$mysqli_reference_params[] =& $actionStr;
foreach($argumentList as &$var) {
    $mysqli_reference_params[] =& $var;
}

call_user_func_array('bind_param_test',  $mysqli_reference_params);

/* OUTPUT:
Decimal: 10
Decimal: 20  */
$sql = "    SELECT  p.`productID`,
                    p.`productCode`,
                    p.`productName`,
                    p.`productDescription`,
                    p.`productPrice`,
                    p.`productRating`,
                    p.`productDateTime`
            FROM `products` as p
            WHERE `p`.`productID` IS NOT NULL ";

        if($searchCode){
            $sql .= "AND p.`productCode` = ? ";
        }
        if($searchName){
            $sql .= "AND p.`productName` = ? ";
        }
        if($searchDescription) {
            $sql .= "AND p.`productDescription` = ? ";
        }
        if($searchPrice) {
            $sql .= "AND p.`productPrice` = ? ";
        }
        if($searchRating) {
            $sql .= "AND p.`productRating` = ? ";
        }
        if($searchDateTime) {
            $sql .= "AND p.`productDateTime` = ? ";
        }

        // Create mysqli_stmt
        $statement = $mysqli->prepare($sql);
        if ($statement instanceof \mysqli_stmt === false) {
            return null;
        }

        // Handle search variables through bind_param()
        $bindParamVarList = array(
            'productCode' => $searchCode,
            'productName' => $searchName,
            'productDescription' => $searchDescription,
            'productPrice' => $searchPrice,
            'productRating' => $searchRating,
            'productDateTime' => $searchDateTime,
        );
        $bindParamVarList = array_filter($bindParamVarList);

        if($bindParamVarList){
            $types = '';
            foreach($bindParamVarList as &$v){

                if(is_numeric($v)){
                    $types .= 'd';
                    $v = (float)$v;
                    continue;
                }

                if(is_string($v)){
                    $types .= 's';
                    continue;
                }
            }

            // call_user_func_array needs references and not values
            $mysqli_reference_params = array();
            $mysqli_reference_params[] =& $types;
            foreach($bindParamVarList as &$bindParamVar) {
                $mysqli_reference_params[] =& $bindParamVar;
            }

            call_user_func_array(array($statement,  'bind_param'),  $mysqli_reference_params);
        }

        $statement->execute();
        $statement->store_result();
        $amount = $statement->num_rows;

        $statement->bind_result($productID,
                                $productCode,
                                $productName,
                                $productDescription,
                                $productPrice,
                                $productRating,
                                $productDateTime
        );

        $products = array();
        $productsSet = array();
        while($statement->fetch()){
            $product = array();
            $product['productID'] = $productID;
            $product['productCode'] = $productCode;
            $product['productName'] = $productName;
            $product['productDescription'] = $productDescription;
            $product['productPrice'] = $productPrice;
            $product['productRating'] = $productRating;
            $product['productDateTime'] = $productDateTime;

            $products[] = $product;
        }

        // JavaScript is only able to work with indexed Array's
        $productsSet[] = $products;
        $productsSet[] = $amount;