PDO preapred stament的功能不起作用并且出错

时间:2017-05-24 04:58:16

标签: php mysql pdo

我使用相同用途的2个函数来接管PDO Preapred Statement,但两者都不起作用。

功能1:

function doSave($array, $table) {
if (count($array) == 0) {
    throw new Exception('Array cant be empty');
} else {
    global $connect;
    //prepare the query first
    $prepare_1 = 'INSERT INTO' . ' ' . $table . ' '; //start preparing
    $columns = array();
    foreach ($array as $key => $value) {
        $columns[] = ':' . $key; //gets all columns and add commas
    }
    foreach ($array as $key => $value) {
        $keye[] =  $key; //gets all columns and add commas
    }
    $keyes = implode(', ', $keye);
    $column = implode(', ', $columns);
    //now you can combine everything and prepare
    $stmt99 = $connect->prepare($prepare_1 .'('.$keyes.')'. ' VALUES (' . $column . ')'); 
    //remember to add the values. also test this section as its not tested

    foreach ($array as $key => $value) {
    $test[] = "':" . $key ."' => ". $value;
         }
        $tests = implode(', ', $test);          
        $stmt99->execute($tests);
}
}

当我插入数据时,我没有错误,也没有数据插入我的数据库

功能2:

function doSave($array, $table) {
if (count($array) == 0) {
    throw new Exception('Array cant be empty');
} else {
    global $connect;
    //prepare the query first
    $prepare_1 = 'INSERT INTO' . ' ' . $table . ' '; //start preparing
    $columns = array();
    foreach ($array as $key => $value) {
        $columns[] = ':' . $key; //gets all columns and add commas
    }
    foreach ($array as $key => $value) {
        $keye[] =  $key; //gets all columns and add commas
    }
    $keyes = implode(', ', $keye);
    $column = implode(', ', $columns);
    //now you can combine everything and prepare
    $stmt99 = $connect->prepare($prepare_1 .'('.$keyes.')'. ' VALUES (' . $column . ')'); 
    //remember to add the values. also test this section as its not tested

    foreach ($array as $key => $value) {
    $test[] = '$stmt99->bindparam('.'":' . $key .'",'. $value.'); ';
         }
        $tests = implode(' ', $test);
            $tests;
        $stmt99->execute();
}
}

使用此功能时出错:

SQLSTATE[HY093]: Invalid parameter number: no parameters were bound

我如何使用该功能:

$array = array('categoryName' => $categoryName, 'categorySort' => $categorySort);
doSave($array, 'category');

这是数组的来源:

if (!empty($_POST["categoryName"])) {
        $categoryName = ($_POST["categoryName"]);
        if (!preg_match("/^[a-zA-Z ]*$/",$categoryName)) {
          $errMsg = "<div class='alert alert-danger text-center'><strong>Hanya boleh huruf.</strong></div>"; 
        }
    }  
    if ($_POST["categorySort"] == $check['categorySort']) {
         $errMsg = "<div class='alert alert-danger text-center'><strong>Urutan sudah digunakan.</strong></div>"; 
    }else{
        $categorySort = ($_POST["categorySort"]);
        if (!is_numeric($_POST['categorySort'])) {
          $errMsg = "<div class='alert alert-danger text-center'><strong>Hanya boleh angka.</strong></div>"; 
        } 
    }

这个2功能可能出错可能同样起作用。函数1(命名为param)函数2(bindparam)?

2 个答案:

答案 0 :(得分:1)

以下未经过全面测试,但显示了我使用echo语句测试时的预期。

在尝试执行语句之前,您应该检查prepare的返回值,因为如果语句未能正确准备,它将返回false。

function doSave( $array, $table ) {
    try{
        /* if you throw exceptions you should catch them!! */

        if( empty( $array ) )throw new Exception('Array cant be empty');
        if( empty( $table ) )throw new Exception('Table name cannot be empty');
        global $connect;

        /* placeholder variables */
        $prepare = $columns = $values = array();
        $result = false;

        $table = preg_replace("@[',\.]@",'',$table);// whatever chars deemed appropriate to replace
        $prepare[]="insert into `{$table}` ";

        /* iterate through source array */
        foreach( $array as $key => $value ) {
            $columns[] = $key;
            $values[ $key ] = $value;
        }

        $strcolumns = implode('`,`',$columns);
        $strplaceholders = ':'.implode(', :',$columns);

        /* append columns and placeholders */
        $prepare[]="( `$strcolumns` ) values ( $strplaceholders );";

        /* finalise sql statement */
        $sql=implode('',$prepare);

        $stmt = $connect->prepare( $sql );
        if( $stmt ){
            /* bind the params */
            foreach( $values as $key => $value ) $stmt->bindParam( ':'.$key, $value );

            /* execute the statement */
            $result = $stmt->execute();
        } else {
            throw new Exception('Error preparing sql statement');
        }
        return $result;
    }catch( Exception $e ){
        exit( $e->getMessage() );
    }
}

我为代码做的假设是像这样的输入数组

$t='mytable';
$a=array(
    'id'    =>  '303',
    'name'  =>  'bob',
    'size'  =>  'small',
    'weight'=>  'heavy'
);

答案 1 :(得分:0)

  

注意:
  您有两个具有相同名称的功能。 PHP如何知道你正在调用哪个函数?

功能2:

foreach ($array as $key => $value) {
    $test[] = '$stmt99->bindparam('.'":' . $key .'",'. $value.'); ';
         }

因为你将它包含在[single]引号中,所以这个值不再是对象方法调用,而只是一个字符串。这意味着当你然后implode这个数组时,你所做的只是一个更长的字符串。

另外,因为你使用的是单引号,PHP不会将值$stmt99识别为PHP对象引用,而是将其字面上理解为美元符号,s字符,t字符,m字符,等....

因此,PDO没有绑定到给定SQL的值。

<强>修正:

 foreach ($array as $key => $value) {
     $stmt99->bindparam(":" . $key , $value);
     }
  unset($key,$value);  // always tidy up after foreach loops.