sourcecode

값이 일정한 bindParam을 사용하는 경우 참조 오류에 의해 파라미터 2를 통과시킬 수 없습니다.

copyscript 2023. 1. 30. 22:15
반응형

값이 일정한 bindParam을 사용하는 경우 참조 오류에 의해 파라미터 2를 통과시킬 수 없습니다.

난 이 코드를 사용하고 있어 좌절감을 넘어섰어

try {
    $dbh = new PDO('mysql:dbname=' . DB . ';host=' . HOST, USER, PASS);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
}
catch(PDOException $e)
{
    ...
}
$stmt = $dbh->prepare('INSERT INTO table(v1, v2, ...) VALUES(:v1, :v2, ...)');
$stmt->bindParam(':v1', PDO::PARAM_NULL); // --> Here's the problem

PDO::PARAM_NULL, null, '',모두 실패하고 다음 오류가 발생합니다.

치명적 오류: /opt/...에서 참조로 매개 변수 2를 전달할 수 없습니다.

를 사용해야 합니다.bindValue,것은 아니다.bindParam

bindParam참조에 의해서 변수를 취득해, 콜시에 값을 취득하지 않는다.bindParamPHP 문서의 코멘트에서 다음과 같은 것을 발견했습니다.

bindValue(':param', null, PDO::PARAM_INT);

추신: 이렇게 하고 싶을 수도 있습니다.bindValue(':param', null, PDO::PARAM_NULL);모두에게 효과가 있었던 것은 아닙니다(Will Shaver씨, 보고해 주셔서 감사합니다.

사용시bindParam()상수가 아닌 변수를 통과해야 합니다.따라서 이 행 앞에 변수를 생성하여 다음과 같이 설정해야 합니다.null

$myNull = null;
$stmt->bindParam(':v1', $myNull, PDO::PARAM_NULL);

다음과 같은 오류 메시지가 나타납니다.

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL);

사용시INTEGER열(즉, 다음과 같습니다)NULLMySQL에서 PDO가 예기치 않은 동작을 합니다.

사용하시는 경우$stmt->execute(Array), 리터럴을 지정해야 합니다.NULL줄 수 없다NULL변수 참조에 의해.이 방법은 사용할 수 없습니다.

// $val is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => $val
));
// will cause the error 'incorrect integer value' when $val == null

하지만 이 방법은 효과가 있습니다.

// $val again is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => isset($val) ? $val : null
));
// no errors, inserts NULL when $val == null, inserts the integer otherwise

PHP 5.4.1을 탑재한 MySQL 5.5.15로 시험해 보았다.

여전히 문제가 있는 경우(파라미터 2를 참조로 전달할 수 없음), PDO에 null을 전달할 뿐만 아니라 null 값을 사용하여 변수를 정의합니다.

bindValue(':param', $n = null, PDO::PARAM_INT);

이게 도움이 됐으면 좋겠다.

같은 문제가 발생하여 bindParam에서 다음 솔루션이 동작하고 있음을 알게 되었습니다.

    bindParam(':param', $myvar = NULL, PDO::PARAM_INT);

삽입할 경우NULL그 때만이valueempty또는'', 단,value가능한 한 빨리 해 주세요.

A) POST 메서드를 사용하여 폼 데이터를 수신하고 그 값을 사용하여 함수 삽입을 호출합니다.

insert( $_POST['productId'], // Will be set to NULL if empty    
        $_POST['productName'] ); // Will be to NULL if empty                                

B) 사용자가 필드를 채우지 않았는지 평가하여 삽입합니다.NULL만약 그렇다면.

public function insert( $productId, $productName )
{ 
    $sql = "INSERT INTO products (  productId, productName ) 
                VALUES ( :productId, :productName )";

    //IMPORTANT: Repace $db with your PDO instance
    $query = $db->prepare($sql); 

    //Works with INT, FLOAT, ETC.
    $query->bindValue(':productId',  !empty($productId)   ? $productId   : NULL, PDO::PARAM_INT); 

    //Works with strings.
    $query->bindValue(':productName',!empty($productName) ? $productName : NULL, PDO::PARAM_STR);   

    $query->execute();      
}

예를 들어, 사용자가 에 아무것도 입력하지 않은 경우productName폼의 필드, 그렇다면$productName될 것이다SET그렇지만EMPTY그래서, 당신은 그것이 맞는지 확인할 필요가 있다.empty()이 경우 삽입하십시오.NULL.

PHP 5.5.17에서 테스트 완료

행운을 빌어요,

몇 가지 답변이 무엇을 해야 하는지에 대한 예를 제시했습니다.하지만 그들은 당신이 왜 그런 일을 해야 하는지 설명해주지 않았어요.

이 메서드는 루프(또는 반복된 문)와 함께 사용됩니다.변수 참조를 바인딩합니다.그래서 뭐랄까...

$stmt = $dbh->prepare('INSERT INTO t1 (v1) VALUES(:v1)');
$stmt->bindParam(':v1', $i, PDO::PARAM_INT);
for ($i = 0; $i < 10; $i++) {
    $stmt->execute();
}

테이블에 0 ~ 9의 값을 삽입합니다.

이것은 분명히 매우 간단한 예이며 다른 보다 효율적인 방법으로 구현될 수 있습니다.여기서는 좀 더 복잡한 논리를 사용할 수 있습니다.그러나 기본 개념은 참조를 변수에 바인딩한 다음 변수의 값을 변경할 수 있다는 것입니다.

를 호출하기 전에 변수를 작성하면 참조의 필요성을 회피할 수 있습니다.그러나 이 경우 변수 참조에 특별히 바인딩하고 싶지 않습니다.값만 바인딩하면 됩니다.그럼 에 정확하게 대응해 주세요.

그냥 하시면 됩니다.bindValue 두 모두 하는 이유를 하기 위해 앞의 bindValuebindParam:

$stmt = $dbh->prepare('INSERT INTO t1 (v1) VALUES(:v1)');
for ($i = 0; $i < 10; $i++) {
    $stmt->bindValue(':v1', $i, PDO::PARAM_INT);
    $stmt->execute();
}

하면만, 「」로 전화할 가 있습니다.bindValue on every iteration of the loop whereas you only needed to call 루프가 반복될 때마다 호출만 하면 됩니다.bindParam한 번 하고 싶지 않아, 근 런 데 니 그 하 냥 까 그 once you aren... that like한 just but anything, can you't안거 doing넌 so번.. once

$stmt->bindValue(':v1', null, PDO::PARAM_INT);

그리고 승인된 답변에 명시된 대로 모든 것이 작동할 것입니다.변수 참조가 아닌 값을 바인딩해야 하기 때문입니다.

다른 답변을 바탕으로 하지만 이 솔루션을 실제로 사용하는 방법에 대해 좀 더 명확하게 설명합니다.

예를 들어 시간 값에 대한 빈 문자열이 있지만 null로 저장하는 경우:

  if($endtime == ""){
    $db->bind(":endtime",$endtime=NULL,PDO::PARAM_STR);
  }else{
    $db->bind("endtime",$endtime);
  }

시간은 문자열로 저장되므로 시간 값에는 PARAM_STR을 사용합니다.

이것을 시험해 보세요.

$stmt->bindValue(':v1', null, PDO::PARAM_NULL); // --> insert null

내 경우 다음을 사용하고 있습니다.

  • SQLite,

  • 플레이스 홀더와 함께 알 수 없는 수의 필드를 처리하기 위해 준비된 스테이트먼트,

  • 모든 이 문자열이고 다음과 같은 것이 없는 사용자가 보낸 AJAX 요청NULL값 및 어

  • I desperately need to insert 꼭 삽입해야 합니다.NULL이는 외부 키 제약(허용값)을 위반하지 않습니다.

Suppose, now user sends with post: 유저가 투고와 함께 송신한다고 가정합니다.$_POST[field1] with value 가치 있게value1이 될 수 ."" ★★★★★★★★★★★★★★★★★」"null" ★★★★★★★★★★★★★★★★★」"NULL".

먼저 이렇게 말씀드리겠습니다.

$stmt = $this->dbh->prepare("INSERT INTO $table ({$sColumns}) VALUES ({$sValues})");

서 ''는{$sColumns}~와 field1, field2, ... ★★★★★★★★★★★★★★★★★」{$sValues}의 표시자?, ?, ....

그리고 나서, 나는 내 것을 수집한다.$_POST 내의 $values 로 대체하다NULLs:

  for($i = 0; $i < \count($values); $i++)
     if((\strtolower($values[$i]) == 'null') || ($values[$i] == ''))
        $values[$i] = null;

이제 다음을 실행할 수 있습니다.

$stmt->execute($values);

기타 바이패스 외부 키 제한 중 하나입니다.

한편, 빈 문자열이 유효한 경우는, 그 필드가 외부 키의 일부인지 아닌지를 확인할 필요가 있습니다(복잡합니다).

언급URL : https://stackoverflow.com/questions/1391777/why-i-am-getting-cannot-pass-parameter-2-by-reference-error-when-i-am-using-bind

반응형