Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

PHP mysql_stmt::fetch() memberikan memori kesalahan fatal PHP habis

Anda akan menemukan bahwa ini terjadi hanya ketika @status adalah NULL atau string.

Masalahnya ada dua:

  1. Tidak seperti variabel lokal , MySQL variabel pengguna mendukung kumpulan tipe data yang sangat terbatas:

    Dokumentasi gagal menyebutkan bahwa tipe data aktual yang digunakan masing-masing adalah BIGINT , DECIMAL(65,30) , DOUBLE , LONGBLOB , LONGTEXT dan LONGBLOB . Mengenai yang terakhir, manual setidaknya menjelaskan:

    Penyimpanan dari tiga tipe data pertama (yaitu untuk nilai integer, desimal dan floating-point) masing-masing membutuhkan 8, 30 dan 8 byte. Tipe data lainnya (yaitu untuk string dan NULL nilai) memerlukan (hingga) 4 gigabyte penyimpanan.

  2. Karena Anda menggunakan versi PHP sebelum v5.4.0, driver MySQL default adalah libmysql , dengan hanya metadata tipe kolom yang tersedia dari server pada pengikatan data—jadi MySQLi mencoba mengalokasikan memori yang cukup untuk menampung setiap nilai yang mungkin (bahkan jika buffer penuh pada akhirnya tidak diperlukan); jadi NULL - dan variabel pengguna bernilai string, yang memiliki kemungkinan ukuran maksimum 4GiB, menyebabkan PHP melebihi batas memori default (dari 128MiB sejak PHP v5.2.0).

Pilihan Anda meliputi:

  • Mengganti tipe data kolom dalam definisi tabel:

    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table (
      status VARCHAR(2)
    ) SELECT @status AS status;
    
  • casting secara eksplisit variabel pengguna ke tipe data yang lebih spesifik:

    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table
      SELECT CAST(@status AS CHAR(2)) AS status;
    
  • Menggunakan variabel lokal, yang dideklarasikan dengan tipe data eksplisit:

    DECLARE status VARCHAR(2) DEFAULT @status;
    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table
      SELECT status;
    
  • Mengatasi masalah dengan memanggil mysqli_stmt::store_result() sebelum mysqli_stmt::bind_result() , yang menyebabkan hasil untuk disimpan di libmysql (di luar batas memori PHP) dan kemudian PHP hanya akan mengalokasikan memori aktual yang diperlukan untuk menyimpan catatan saat mengambilnya:

    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result( $status );
    $stmt->fetch();
    
  • Meningkatkan batas memori PHP sehingga dapat mengakomodasi alokasi buffer 4GiB (walaupun kita harus menyadari implikasi pada sumber daya perangkat keras dari melakukannya)—misalnya, untuk menghapus batasan memori sepenuhnya (walaupun waspadai potensi efek samping negatif dari melakukan hal ini, misalnya dari kebocoran memori asli):

    ini_set('memory_limit', '-1');
    
  • Mengkompilasi ulang PHP, dikonfigurasi untuk menggunakan driver mysqlnd asli (disertakan dengan PHP sejak v5.3.0, tetapi tidak dikonfigurasi sebagai default hingga PHP v5.4.0) alih-alih libmysql:

    ./configure --with-mysqli=mysqlnd
    
  • Upgrade ke PHP v5.4.0 atau yang lebih baru sehingga mysqlnd digunakan secara default.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara mengatur hari pertama dalam seminggu ke Senin saat menggunakan Minggu (Tanggal) di PHP/MySQL?

  2. Cara Mendapatkan Catatan dari Hari Ini di MySQL

  3. Kesalahan sintaks SQL dekat desc

  4. Server mengalami kesalahan internal atau kesalahan konfigurasi dan tidak dapat menyelesaikan permintaan Anda

  5. Bagaimana menerapkan tipe data char(N) alih-alih varchar(N) di bidang model Django