【问题标题】:bind param count first argument绑定参数计数第一个参数
【发布时间】:2015-11-29 21:08:40
【问题描述】:

我有以下行:

$formatsArray = $_POST['formats'];
$topicsArray = $_POST['topics'];


// Converting the array into individual strings
$formats = implode(",", $formatsArray);
$topics = implode(",", $topicsArray);


  // Prepare the statement
    $resources = $con->prepare("SELECT * FROM resources WHERE
            (format IN (?))
             AND (topic IN (?))");

    // Bind the statement
    $resources->bind_param('ss',$formats, $topics);

问题是从一个数组派生的主题可以包含多个字符串,但“s”只能识别 1。我希望主题数组有 10 个条目,而不是 10 个条目,格式相同.

我正在考虑计算数组的大小并在每次迭代中添加一个 s,但不确定如何。 任何帮助将不胜感激。

   // Count array
    $formatCount = count($formatsArray);
    $topicCount = count($topicsArray);

【问题讨论】:

  • 不可能。占位符代表 SINGLE 值。填充到占位符中的 csv 字符串 a,b,c 不会是 in 考虑的三个独立的东西,它将是 ... IN('a,b,c') - 一个值。您必须动态构建一个查询字符串,并根据您的值输入尽可能多的?,或者完全使用其他东西。
  • 您将单个值绑定到每个占位符 ?.... 所以值数组不会绑定到单个占位符
  • 数组已被转换为字符串,因此实例将返回创意生成,客户开发问题是我想单独评估“创意生成”和“客户开发”
  • 这是一个全新的问题

标签: php mysql mysqli prepared-statement


【解决方案1】:

那么这个怎么样:

<?php  
    $con = new mysqli("localhost", "USERNAME", "PASSWORD", "DATABASE");

    $formatsArray = array('a','b','c','d',);
    $topicsArray = array('x','y','z',);

    $sql = 'SELECT * FROM resources WHERE (format IN (FORMAT_REPLACE_ME)) AND (topic IN (TOPIC_REPLACE_ME))';

    $formatsPlaceholders = makePlaceHolders($formatsArray);
    $topicsPlaceholders = makePlaceHolders($topicsArray);

    $sql = str_replace('FORMAT_REPLACE_ME', $formatsPlaceholders, $sql);
    $sql = str_replace('TOPIC_REPLACE_ME', $topicsPlaceholders, $sql);

    //error_log(print_r($sql,1).' '.__FILE__.' '.__LINE__,0);

    try {
        $s = $con->prepare($sql);

        $vals = array_merge($formatsArray, $topicsArray);

        // from http://stackoverflow.com/a/31562035/1814739
        $typDfs = str_repeat( 's' , count( $vals ) );
        $params = array( $typDfs );
        foreach ( $vals as $k => $v ) {
            ${ 'varvar' . $k } = $v;
            $params[] = &${ 'varvar' . $k }; # provide references
        }
        call_user_func_array( array( $s, 'bind_param' ) , $params );

        $s->execute();

        $output = array();
        $res = $s->get_result();
        while ($row = $res->fetch_array(MYSQLI_NUM))
        {
            //error_log(print_r($row,1).' '.__FILE__.' '.__LINE__,0);
            $output []= array(
                'id' => $row[0],
                'format' => $row[1],
                'topic' => $row[2],
            );
        }

        $s->close();

        sanitize_output($output);
    }
    catch (\Exception $e) {
        error_log(print_r($e->getMessage(),1).' '.__FILE__.' '.__LINE__,0);
    }

    function makePlaceHolders($arr){
        $ph = '';
        for ($i = 1; $i <= count($arr); $i++) {
            $ph .= '?,';
        }
        return rtrim($ph,',');
    }

    function sanitize_output(array &$arr, array $args=array()) {
        array_walk_recursive($arr,'so',$args);
    }
    function so(&$v,$k,$args) {
        $excludes = isset($args['excludes']) ? $args['excludes'] : array();
        if (!in_array($k,$excludes)) {
            $v = trim($v);
            $v = (get_magic_quotes_gpc()) ? stripcslashes($v) : $v;
            $v = htmlspecialchars($v);
        }
    } 
?>
<html>
<body>
    <ul>
        <?php foreach($output as $k => $o) { ?>
        <li><?php echo $o['id']; echo $o['format']; echo $o['topic']; ?></li>
        <?php } ?>
    </ul>
</body>
</html>

【讨论】:

  • 感谢您的回复。我使用 mysqli 作为 pdo 的对立面
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 2018-03-22
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
相关资源
最近更新 更多