2015-11-23 13 views
6

Questo è il caso: Ho un file di dump da 2 GB chiamato myDB.sql. È un file di dump che cancella un database esistente e ne crea uno nuovo, con viste e trigger. Così ho la stringa myDB_OLD diffusa per molte linee del codice. Vorrei cambiare queste occorrenze di stringhe a myDB_NEW. Potrei farlo facilmente usando notePad ++. Ma il blocco note non apre un file da 2 GB. Quello che ho fatto è un codice PHP che legge riga per riga e trova e sostituisce la stringa che voglio.Qual è il limite di dimensioni di una variabile Php quando si memorizza una stringa?

Questo è il codice:

$myfile2 = fopen("myDB.sql", "r") or die("Unable to open file!");//Reads the file 
while (!feof($myfile2)) {//Pass trough each line 
    $str=fgets($myfile2);//Store the line inside a variable 
    if (preg_match("/myDB_OLD/",$str)) {//If the string I want to change exists - replace it and conacatenate 
     $newStr .= str_replace("myDB_OLD","myDB_NEW",$str); 
    } 
    else {//If not concatenate it 
     $newStr .=$str; 
    } 
}//End of while 
fclose($myfile2); 
//Save the newStr in a new file named 
$myfile = fopen("newDB.sql", "w") or die("Unable to open file!"); 
fwrite($myfile, $newStr); 
echo "finished"; 

Questo codice recuperare ogni riga del file cambia la stringa, concatenare in variabile e crea un nuovo file. Dovrebbe funzionare ma non lo è. Non so perché. Sto usando xdebug per capire qual è il problema, ma senza fortuna.

Quindi cambio l'approccio. Invece di salvare ogni riga in una variabile, la salverò direttamente in un file e questo funziona bene.

Questo è il codice nuovo:

$myfile = fopen("newDB.sql", "w") or die("Unable to open file!");//Creates a new file "newDB.sql" 

$myfile2 = fopen("myDB.sql", "r") or die("Unable to open file!");//Reads the file 
while (!feof($myfile2)) {//Pass trough each line 
     $str=fgets($myfile2);//Store the line inside a variable 
     if (preg_match("/myDB/",$str)) {//If the string I want to change exists - replace it . (Do not concatenate) 
      $strRep=str_replace("myDB","myDB_NEW",$str); 
     } 
     else { 
      $strRep =$str; 
     } 

     fwrite($myfile, $strRep);// Add the new line to the file "newDB.sql" 
}//End of while 
fclose($myfile); 
fclose($myfile2); 

echo "finished"; 

Ok, ho risolto il mio problema, ma solleva un pensiero. Qual è il problema del primo codice? Penso che il problema sia la quantità di informazioni da memorizzare in una variabile PHP, 2Gb. Quindi, c'è un limite nella dimensione di una variabile PHP per memorizzare il valore, in questo caso, una stringa? Se sì, come posso controllarlo o modificarlo? Qualunque variabile php.ini?

+0

Che errore ha? E qual è il limite di memoria impostato nel tuo file php.ini? –

+0

E come è possibile importare un dump MySQL su qualsiasi nome di database, perché è necessario farlo anche in primo luogo? –

+0

Per la prima domanda. Non c'è errore Xdebugt non genera alcun errore. Si ferma solo per lavorare all'interno del ciclo. Per quanto riguarda il limite di memoria, potrei controllare se sono nuovo, questo è il motivo per cui non l'ho verificato come il mio primo approccio prima di ricablare il codice. Per la seconda domanda.Era una situazione specift e non so se cambio il nome del database cambierà tutte le occorrenze all'interno del file dump come crea trigger ed ecc. Posso testarlo. Lo sai? – zwitterion

risposta

7

Quindi, esiste un limite di dimensioni per una variabile Php per memorizzare il valore, in questo caso, una stringa?

Sì. A string can be as large as up to 2GB (2147483647 bytes maximum). Non è possibile ignorare questo limite aumentando la direttiva memory_limit in php.ini.

From php7 non c'è tale limitazione in un sistema a 64 bit:

Supporto per le stringhe di lunghezza> = 2^31 byte 64 bit costruisce.

+2

Buono. Non ci avevo nemmeno pensato. Ma, come accennato in precedenza, è probabile che un'applicazione PHP con oltre 2 GB valga la pena di refactoring :) –

+0

Di cosa stai parlando @Rob Quist ??? un'applicazione PHP che utilizza oltre 2 GB? Che cosa??? Ha 2 GB di dati. non 2 GB di roba PHP ... Sta scrivendo un codice php per copiare su un database da 2 GB ... Sto lavorando con un database da 10 GB in questo momento e ho lavorato con database fino a 200 GB nel passato ... Perché sono stai dicendo che dovrei fare un po 'di refactoring? Ho un sacco di dati, e questo è tutto. Il mio codice php non è colpa. Niente è colpa. Ci sono solo un sacco di utenti e un sacco di immissione manuale e automatica dei dati ... Ogni singola riga in quel database è utile e necessaria ... –

+0

Voglio dire se il codice sta usando 2GB di RAM in un singolo momento, il suo vale la pena refactoring. Non stavo parlando di dati, ovviamente. –

3

Il numero massimo di byte consentito da uno script è impostato su php.ini. Cerca memory_limit. Questo è 16Mb dopo PHP 5.2.0 come predefinito!

questo può essere cambiato facendo una:

ini_set('memory_limit','24M'); 

La massima size of a string è di 2 GB in PHP, probabilmente a causa delle limitazioni d'indirizzo, se consentito dal memory_limit.

+1

Infatti. Anche se probabilmente stai facendo qualcosa di sbagliato se hai bisogno di grandi quantità lì. Il metodo line-by-line che hai fatto è una soluzione adeguata. –

+3

Inoltre, questo limite può essere aumentato usando 'set_memory_limit()'. – Peter

+2

@RobQuist Hai perfettamente ragione, anche se a volte durante l'analisi di file xls o pdf la dimensione può crescere oltre 16M – Peter

Problemi correlati