Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.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 警告:PDOStatement::execute():SQLSTATE[HY093]:无效参数编号:绑定变量的数量与中的令牌数量不匹配_Php_Database_Data Binding_Code Snippets - Fatal编程技术网

Php 警告:PDOStatement::execute():SQLSTATE[HY093]:无效参数编号:绑定变量的数量与中的令牌数量不匹配

Php 警告:PDOStatement::execute():SQLSTATE[HY093]:无效参数编号:绑定变量的数量与中的令牌数量不匹配,php,database,data-binding,code-snippets,Php,Database,Data Binding,Code Snippets,我正在使用PHP PDO,我有以下问题: Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /var/www/site/classes/enterprise.php on line 63 这是我的密码: public function getCompaniesBy

我正在使用PHP PDO,我有以下问题:

Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /var/www/site/classes/enterprise.php on line 63
这是我的密码:

    public function getCompaniesByCity(City $city, $options = null) {
  $database = Connection::getConnection();

  if(empty($options)) {
   $statement = $database->prepare("SELECT * FROM `empresas` WHERE `empresas`.`cidades_codigo` = ?");
   $statement->bindValue(1, $city->getId());
  }
  else {
   $sql = "SELECT * FROM `empresas`
    INNER JOIN `prods_empresas` ON `prods_empresas`.`empresas_codigo` = `empresas`.`codigo` WHERE ";

   foreach($options as $option) {
    $sql .= '`prods_empresas`.`produtos_codigo` = ? OR ';
   }

   $sql = substr($sql, 0, -4);
   $sql .= ' AND `empresas`.`cidades_codigo` = ?';

   $statement = $database->prepare($sql);

   echo $sql;

   foreach($options as $i => $option) {
    $statement->bindValue($i + 1, $option->getId());
   }

   $statement->bindValue(count($options), $city->getId());
  }

  $statement->execute();

  $objects = $statement->fetchAll(PDO::FETCH_OBJ);
  $companies = array();

  if(!empty($objects)) {
   foreach($objects as $object) {
    $data = array(
     'id' => $object->codigo,
     'name' => $object->nome,
     'link' => $object->link,
     'email' => $object->email,
     'details' => $object->detalhes,
     'logo' => $object->logo
    );

    $enterprise = new Enterprise($data);
    array_push($companies, $enterprise);
   }

   return $companies;
  }
 }

由于您已在循环中生成了
$i+1
,因此
计数($options)
将等于生成重复绑定的最后一个
$i+1
。请尝试

 foreach($options as $i => $option)
 { 
      $statement->bindValue($i + 1, $option->getId()); 
 }

 $statement->bindValue(count($options)+1, $city->getId()); 

看起来您正在尝试构建一个长(?)系列的“或”比较:
如果(x=1)或(x=2)或(x=3)等…
。您可能会发现更容易将其替换为:

$cnt = count($options);
if ($cnt > 0) {
   $placeholders = str_repeat(', ?', $cnt - 1);
   $sql .= 'WHERE '`prods_empresas`.`produtos_codigo` IN (?' . $placeholders . ')';
}
如果有5个选项,你会得到

 WHERE prods_empresas.produtos_condigo IN (?, ?, ?, ?, ?)
然后将值绑定到:

$pos = 1;
foreach ($options as $option) {
   $statement->bindValue($pos, $option->getId());
   $pos++
}

绑定参数的数量与SQL中的绑定数量不匹配。仔细检查
的数量和绑定参数的数量是否相同

此外,如果您试图绑定一个不存在的参数,
HY093
将显示:

$stmt = "INSERT INTO table VALUES (:some_value)";
$stmt->bindValue(':someValue', $someValue, PDO::PARAM_STR);
查看
:some_值
:some值
不匹配!解决办法是:

$stmt = "INSERT INTO table VALUES (:some_value)";
$stmt->bindValue(':some_value', $someValue, PDO::PARAM_STR);

SQL中的位置参数从1开始。您通过绑定到$options循环中的位置
$i+1
来处理此问题

但随后将
cidades_codigo
的最后一个参数绑定到位置
count($options)
,这将覆盖$options循环中设置的最后一个参数

您需要将最后一个参数绑定到位置
count($options)+1


FWIW,您根本不需要
bindValue()
。只需将一组参数传递给
execute()
就更容易了。下面是我编写此函数的方法:

public function getCompaniesByCity(City $city, $options = null) {
  $database = Connection::getConnection();

  $sql = "SELECT * FROM `empresas` WHERE `empresas`.`cidades_codigo` = ?"

  $params = array();
  $params[] = $city->getId();

  if ($options) {
    $sql .= " AND `prods_empresas`.`produtos_codigo` IN (" 
      . join(",", array_fill(1, count($options), "?") . ")";
    foreach ((array)$options as $option) {
      $params[] = $option->getId();
    }
  }

  $statement = $database->prepare($sql);

  echo $sql;

  $statement->execute($params);
  . . .

还要确保检查
prepare()
execute()
的返回值,如果有错误,它将是
false
,您需要检查并报告错误。或者启用PDO在出错时抛出异常。

我遇到了这个问题,因为在命名参数映射数组中有额外的条目传递给PDO::Statement->execute()


我不明白这是一个答案还是一个评论。请你重新措辞好吗?
$args=array (":x" => 17 );
$pdo->prepare("insert into foo (x) values (:x)");
$pdo->execute($args); // success
$args[':irrelevant']=23;
$pdo->execute($args) // throws exception with HY093