2010-01-12 16 views
32

Ok, questo è un problema strano, quindi ti prego di sopportare me come spiego.Passa per problema di riferimento con PHP 5.3.1

Abbiamo aggiornato i nostri server di sviluppo da PHP 5.2.5 a 5.3.1.

Caricamento il nostro codice dopo l'interruttore, iniziamo a ricevere errori come:

Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in /home/spot/trunk/system/core/Database.class.php on line 105

la linea menzionata (105) è la seguente:

call_user_func_array(Array($stmt, 'bind_param'), $passArray); 

abbiamo cambiato la linea per la seguente:

call_user_func_array(Array($stmt, 'bind_param'), &$passArray); 

a questo punto (perché allow_call_time_pass_reference) è spento, php genera questa:

Deprecated: Call-time pass-by-reference has been deprecated in /home/spot/trunk/system/core/Database.class.php on line 105

Dopo aver provato a risolvere il problema per qualche tempo, ho rotto e impostare allow_call_time_pass_reference su on.

, sbarazzandosi del l'avvertimento Deprecated, ma ora l'avviso Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference sta gettando ogni volta, con o senza il riferimento.

Non ho idea di come risolvere questo problema. Se il metodo di destinazione fosse mio, farei semplicemente riferimento ai vars in entrata nella dichiarazione func, ma è un metodo (relativamente) nativo (mysqli).

Qualcuno ha provato questo? Come posso aggirarlo?

Grazie.

+0

Inoltre, nel codice sopra $ stmt è un oggetto restituito dal mysqli :: preparare – Spot

+1

Ho anche avuto questo problema e ha trovato [questo] (https://sixohthree.com/1486/migrating-to-php-5-3-call_user_func_array) post sul blog che mi ha aiutato molto. – cb0

risposta

16

Si passa una matrice di elementi ($ passArray). Il secondo elemento all'interno dello dell'array passato deve essere un riferimento, poiché è proprio l'elenco degli elementi che si stanno passando alla funzione.

+0

In realtà hai ragione. Tuttavia fare riferimento a questa variabile non aiuta neanche. Hmmmm – Spot

+4

Ok, risolto questo creando una matrice fittizia, facendo riferimento ai valori dal principale. È piuttosto triste che questo sia stato richiesto per essere onesti. :) Grazie! – Spot

+0

Gentile Spot, ho un problema simile. hai qualche suggerimento. http://stackoverflow.com/questions/23290490/mysqli-prepared-statements-error?noredirect=1#comment35651490_23290490 –

0

Penso che le funzioni mysqli_bind_param() e mysqli_bind_result() siano molto scomode da utilizzare. Ho riscontrato la stessa difficoltà con la quale descrivevi di usarli in combinazione con call_user_func_array()

La mia soluzione era smettere di usare mysqli e usare invece PDO_mysql. Ha un utilizzo molto più semplice:

$pdoStmt->execute($passArray); 
+0

Pensavo che PDO_mysql fosse deprecato? – Spot

+0

No, per niente. Cosa diavolo ti ha dato quell'idea? –

+0

@Spot: 'php_mysql.so' non è raccomandato (non deprecato),' pdo_mysql.so' è molto raccomandato. –

-1

Il secondo paramero Deve essere un array. a quanto pare questo è stato applicato solo in 5.3

+0

E è un array. – Spot

+0

cosa c'è in quella matrice? – DeveloperChris

2

Penso che ciò che è deprecato è passare un riferimento attraverso una funzione. Nella definizione della funzione fai qualcosa come:

function(&$arg) { 

} 

Questo non ti aiuta molto ma probabilmente non hai bisogno di passare comunque il riferimento. Immagino che potresti provare una funzione wrapper.

function wrapper($stmt, &$passArray) { 
    call_user_func_array($stmt, $passArray); 
} 
45

Ho appena sperimentato questo stesso problema, chiamando bind_param via call_user_func_array e passando un array di parametri. La soluzione è modificare i valori nella matrice a cui fare riferimento. Non è elegante ma funziona.

call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced($passArray)); 

function makeValuesReferenced($arr){ 
    $refs = array(); 
    foreach($arr as $key => $value) 
     $refs[$key] = &$arr[$key]; 
    return $refs; 

} 
+2

mi hai salvato la vita – KennyPowers

6

In realtà, essere consapevoli che c'è un bug con PHP 5.3.1 in materia di riferimenti e tutta call famiglia di funzioni:

PHP Bugs #50394: Reference argument converted to value in __call

Il comportamento che state vedendo potrebbe essere un risultato di questo bug e qualsiasi tentativo di risolverlo in codice può causare problemi a lungo termine.

Il problema è stato risolto nella versione SVN di PHP. Fino al rilascio della versione 5.3.2, è possibile compilare una nuova versione per l'uso o eseguire il downgrade a una versione precedente.

3

Stavamo vivendo lo stesso problema con questo codice:

call_user_func(array($strCartHandler, 'CartPurchaseEvent'), $strCartEvent, $objToUser, null, $this); 

La mia soluzione era di saltare call_user_func del tutto e fare questo:

$strCartHandler::CartPurchaseEvent($strCartEvent, $objToUser, null, $this); 
0

Ciò volontà lo aiuta:

<?php 
call_user_func_array(Array($stmt, 'bind_param'), array(&$passArray)); 

function bind_param ($val) 
{ 
    $val = (is_array($val)) ? $val[0] : $val; 

    // operations... 
} 

?> 
0

Ho un problema simile, il codice attuale non funzionava:

$query="Select id,name FROM mytable LIMIT ?,?"; 
$params=Array('ii'); 
array_push($params,$from_var); 
array_push($params,$to_var); 
... 
$stmt=$link->prepare("$query"); 
$ref=new ReflectionClass('mysqli_stmt'); 
$method=$ref->getMethod("bind_param"); 
$method->invokeArgs($stmt,$params); 
... 

E ha detto che "Parametro 2 per mysqli_stmt :: bind_param() dovrebbe essere un punto di riferimento, il valore dato"

E poi, in preda alla disperazione, ho cercato di prendere $ from_var e $ to_var tra virgolette. E ha funzionato!

$params=Array('ii'); 
array_push($params,"$from_var"); 
array_push($params,"$to_var"); 

Speranza, che aiuterà qualcuno, buona fortuna :)

Problemi correlati