Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 20
  1. #1

    PHP - PDO bindValue in ciclo foreach

    Buongiorno a tutti,

    sto migrando una struttura a PDO ed ho il seguente problema, faccio una query e ne ciclo i valori in un foreach, all'interno di questo ciclo devo eseguire 2 query con dei valori ricavati dalla principale.

    Entrambe le query che sarebbero innestate, le preparo fuori dal ciclo e nel ciclo vado semplicemente a cambiare i valori con bindValue, in questo modo non ripreparo la query N volte.

    Utilizzando debugDumpParams, mi sono reso conto che il bind punta una volta alla query esatta e al secondo ciclo punta ad un'altra....il che effettivamente avrebbe anche una logica, se fuori dal ciclo ho 2 o più prepared query, come fa a sapere a quela far riferimento?
    Premetto che i placeholder delle query sono tutti diversi, ma non riesco a uscirne, se la query esterna al ciclo è una sola tutto ok.

    Es.

    Codice PHP:
    $database->prepare("SELECT ... FROM tabella_1 ....");

    # Vari bind per la query 1

    $database->prepare("SELECT ... FROM tabella_2 ....");
    $database->prepare("SELECT ... FROM tabella_3 ....");

    foreach(
    $database->resultset() as $row){

        
    # Vari bind query 2 con valori ricavati da $row
        # Resultset query 2

        # Vari bind query 3 con valori ricavati da $row
        # Resultset query 3

        # Operazioni con i vari risultati dalle varie query


    Grazie
    SK

  2. #2
    Se utilizzi sempre la stessa istanza ($database) immagino che venga effettuato il bind e venga eseguita sempre l'ultima query caricata.
    "Mai discutere con un idiota. Ti trascina al suo livello e ti batte con l'esperienza." (Oscar Wilde)

  3. #3
    In realtà, facendo debugDumpParams al primo ciclo prende la query corretta, al secondo no, ma a parte questo che potrebbe essere una casualità, ho provato a fare tipo $records = $database->..., ma non cambia nulla ho ricevo errori.
    In un altra pagina ho una query da cui eseguo il ciclo e sempre fuori, una seconda query come nel caso dell'esempio e li funziona tutto a questo punto sarà un caso, mi aspetterei che essendo i placeholder diversi si recuperasse la query corretta, ma come dicevo e giustamente hai fatto notare anche tu, se l'istanza è sempre quella è anche normale in un certo senso.
    Ma cosa dovrei fare? Istanziare più volte la calsse con nomi diversi? $database1, $database2, ecc, ecc, boh.
    Riusciresti a farmi un banale esempio, che magari non ho afferrato?

    Grazie

  4. #4
    Quote Originariamente inviata da serialkiller Visualizza il messaggio
    Ma cosa dovrei fare? Istanziare più volte la calsse con nomi diversi? $database1, $database2, ecc, ecc, boh.
    Esatto. Altrimenti, se vuoi utilizzare un'unica istanza devi inizializzarla all'interno del while prima di eseguirla:

    Codice PHP:
    $database->prepare("SELECT ... FROM tabella_1 ....");

    # Vari bind per la query 1

    foreach($database->resultset() as $row){

        
    $database->prepare("SELECT ... FROM tabella_2 ....");
        
    # Vari bind query 2 con valori ricavati da $row
        # Resultset query 2
        
    $resultset2 $database->resultset();

        
    $database->prepare("SELECT ... FROM tabella_3 ....");
        
    # Vari bind query 3 con valori ricavati da $row
        # Resultset query 3
        
    $resultset3 $database->resultset();

        
    # Operazioni con i vari risultati dalle varie query
        
    $resultset2 ...
        
    $resultset3 ...


    "Mai discutere con un idiota. Ti trascina al suo livello e ti batte con l'esperienza." (Oscar Wilde)

  5. #5
    Si, se sono dentro al ciclo non ci sono problemi, anche perchè vengono eseguite proceduralmente quindi non ci sono problemi di sorta.
    Vorrei tenerle fuori per snellire la cosa, query innestate in un ciclo sono sicuramente peggiori rispetto al preparare la query e nel ciclo semplicemente bindare i vari parametri senza ripreparare ogni volta la query.
    Mi sfugge il perchè funzioni se le query sono 2.
    Alla fine dovrei fare una cosa del genere:
    Codice PHP:
    $database1 = new Database();
    $database2 = new Database();
    $database3 = new Database();

    $database1->prepare("Select ..... 1 ....");

    # Vari bind query 1

    $database2->prepare("Select ..... 2 ....");
    $database3->prepare("Select ..... 3 ....");

    foreach(
    $database1->resultset() as $row){

        
    # Vari bind query 2 con valori ricavati da $row
        # Resultset query 2
        
        # Vari bind query 3 con valori ricavati da $row
        # Resultset query 3      


    Faccio delle prove che sicuramente funzioneranno, speravo ci fosse un modo più semplice per poter usare la stessa istanza.

  6. #6
    Morale, cos'è più controproducente, instanziare N volte una classe o innestare query in un ciclo, sicuramente la seconda non è il massimo, alla prima non saprei rispondermi con sicurezza.

  7. #7
    Il bindValue() lo fai comunque all'interno del ciclo while ed è questo che potrebbe comportare un eventuale spreco di risorse. Col prepare() non fai altro che assegnare una stringa (la query da eseguire) all'istanza per cui che il prepare tu lo faccia dentro o fuori dal ciclo while non credo che cambi molto.
    "Mai discutere con un idiota. Ti trascina al suo livello e ti batte con l'esperienza." (Oscar Wilde)

  8. #8
    Mah, leggendo un po' in giro ho sempre letto che è molto meglio fare il prepare statement esternamente al ciclo e internamente fare il bind dei valori proprio per averne dei benefici, tra i quali ridurre le sql injection.
    Per quel che ne so io, è come se viaggiassero su due canali diversi, il prepare e i valori in bind o in un array (che poi è praticamente quasi la stessa cosa), quindi a ragion di logica se tu prepari la query una sola volta e ti limiti a passargli i valori da sostituire, senza ogni volta ripreparare la query dovresti averne dei benefici.

    Prepared statements allow you to make multiple similar queries more efficiently. You can prepare (for example) an insert statement, then loop over it with multiple bits of data and get a performance boost as the database has less work to do as it doesn't have to set it up each time.

    Tanto per citarne una, o dal sito ufficiale:

    Calling PDO:repare() and PDOStatement::execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information, and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters.

    Quindi parrebbe che di differenza c'è ne sia.

  9. #9
    Quote Originariamente inviata da serialkiller Visualizza il messaggio
    Prepared statements allow you to make multiple similar queries more efficiently. You can prepare (for example) an insert statement, then loop over it with multiple bits of data and get a performance boost as the database has less work to do as it doesn't have to set it up each time.
    Si però qui si parla della stessa query nel senso che prepari una singola query di inserimento e poi cicli sui parametri da inserire. Nel tuo caso cerchi di eseguire 2 query differenti.
    "Mai discutere con un idiota. Ti trascina al suo livello e ti batte con l'esperienza." (Oscar Wilde)

  10. #10
    "make multiple similar queries" ...è più di una.

    Comunque qui il concetto è se fosse uguale o meno fare il prepare internamente o esternamente al ciclo.

    "then loop over it with multiple bits of data and get a performance boost"

    o

    "will be issued multiple times with different parameter values optimizes the performance of your application"

    Con le vecchie funzioni mysql_ non era fattibile in alcun modo se si presentava la necessità di eseguire query in un ciclo, con pdo o msqli_ non in modo procedurale si ha la possibilità di, in parole spartane: mysql toh, questa è la query tienila li che poi ti passo i parametri N volte e tu riesegui la stessa cosa, semplicemente cambiando i valori, senza rifarla tutta da capo.
    Che poi sia una query o 10 il concetto non cambia, anzi.

    Purtroppo in giorni di ricerca non ho trovato esempi in merito, son sempre al massimo 2 query, una principale con il suo ciclo e una preparata esternamente e "bindata" (passami il termine ), nel ciclo, ovuque si consiglia di preparare anche la seconda esternamente, ma casi in cui le query da innestare e preparare esternamente fossero più di una non ne ho trovati o spesso la cosa si risolveva ottimizzando la query con JOIN o comunque riducendo le query ad una sola.

    Ora ovviamente istanziando più volte la classe o meglio ho fatto un clone

    Codice PHP:
    $database2 = clone $database
    funziona, ma non mi pare il massimo, poi magari è l'unico modo.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.