Pertanyaan PHP: “Pemberitahuan: Variabel tidak terdefinisi”, “Pemberitahuan: Indeks tidak terdefinisi”, dan “Pemberitahuan: Pengimbangan tidak terdefinisi”


Saya menjalankan skrip PHP, dan terus mendapatkan kesalahan seperti:

Perhatikan: Variabel tidak terdefinisi: my_variable_name di C: \ wamp \ www \ mypath \ index.php pada baris 10

Perhatikan: Indeks tidak terdefinisi: my_index C: \ wamp \ www \ mypath \ index.php on line 11

Baris 10 dan 11 terlihat seperti ini:

echo "My variable value is: " . $my_variable_name;
echo "My index value is: " . $my_array["my_index"];

Apa arti kesalahan ini?

Mengapa mereka muncul tiba-tiba? Saya terbiasa menggunakan skrip ini selama bertahun-tahun dan saya tidak pernah punya masalah.

Apa yang harus saya lakukan untuk memperbaikinya?

Ini adalah pertanyaan Referensi Umum agar orang-orang menautkan sebagai duplikat, alih-alih harus menjelaskan masalah itu berulang kali. Saya merasa ini diperlukan karena sebagian besar jawaban dunia nyata pada masalah ini sangat spesifik.

Diskusi Meta Terkait:


948


asal


Jawaban:


Perhatikan: Variabel tidak terdefinisi

Dari kebijaksanaan yang luas dari PHP Manual:

Mengandalkan nilai default dari variabel terinisialisasi bermasalah dalam kasus termasuk satu file ke yang lain yang menggunakan nama variabel yang sama. Ini juga merupakan jurusan risiko keamanan dengan register_globals dihidupkan. E_NOTICE kesalahan level dikeluarkan dalam kasus bekerja dengan variabel terinisialisasi, namun tidak dalam kasus elemen tambahan ke array terinisialisasi. isset () konstruksi bahasa dapat digunakan untuk mendeteksi apakah suatu variabel telah diinisialisasi. Selain itu dan lebih ideal adalah solusi dari kosong() karena tidak menghasilkan pesan peringatan atau kesalahan jika variabel tidak diinisialisasi.

Dari Dokumentasi PHP:

Tidak ada peringatan yang dihasilkan jika variabel tidak ada. Itu berarti       kosong() pada dasarnya adalah ekuivalen yang ringkas ! isset ($ var) || $ var      == salah.

Ini berarti Anda hanya bisa menggunakannya empty() untuk menentukan apakah variabel ditetapkan, dan selain itu memeriksa variabel terhadap yang berikut, 0,"",null.

Contoh:

$o = [];
@$var = ["",0,null,1,2,3,$foo,$o['myIndex']];
array_walk($var, function($v) {
    echo (!isset($v) || $v == false) ? 'true ' : 'false';
    echo ' ' . (empty($v) ? 'true' : 'false');
    echo "\n";
});

Uji cuplikan di atas di 3v4l.org editor PHP online

Meskipun PHP tidak memerlukan deklarasi variabel, ia merekomendasikannya untuk menghindari beberapa kerentanan keamanan atau bug di mana orang akan lupa untuk memberikan nilai ke variabel yang akan digunakan nanti di skrip. Apa yang dilakukan PHP dalam kasus variabel yang tidak dideklarasikan adalah masalah kesalahan tingkat yang sangat rendah, E_NOTICE, yang bahkan tidak dilaporkan secara default, tetapi Manual menyarankan untuk mengizinkan selama pengembangan.

Cara untuk mengatasi masalah ini:

  1. Disarankan: Deklarasikan variabel Anda, misalnya ketika Anda mencoba menambahkan string ke variabel yang tidak terdefinisi. Atau gunakan isset() / !empty()  untuk memeriksa apakah mereka dinyatakan sebelum merujuk mereka, seperti dalam:

    //Initializing variable
    $value = ""; //Initialization value; Examples
                 //"" When you want to append stuff later
                 //0  When you want to add numbers later
    //isset()
    $value = isset($_POST['value']) ? $_POST['value'] : '';
    //empty()
    $value = !empty($_POST['value']) ? $_POST['value'] : '';
    

    Ini telah menjadi jauh lebih bersih dari PHP 7.0, sekarang Anda dapat menggunakan operator penggabungan nol:

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. Setel pengendali kesalahan khusus untuk E_NOTICE dan mengalihkan pesan dari output standar (mungkin ke file log):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
    
  3. Nonaktifkan E_NOTICE dari pelaporan. Cara cepat untuk mengecualikan saja E_NOTICE aku s:

    error_reporting( error_reporting() & ~E_NOTICE )
    
  4. Menekan kesalahan dengan @ operator.

catatan: Sangat disarankan untuk menerapkan hanya titik 1.

Perhatikan: Indeks tidak terdefinisi / Undefined offset

Pemberitahuan ini muncul ketika Anda (atau PHP) mencoba mengakses indeks array yang tidak terdefinisi.

Cara untuk mengatasi masalah ini:

  1. Periksa apakah indeks ada sebelum Anda mengaksesnya. Untuk ini, Anda bisa menggunakannya isset() atau array_key_exists():

    //isset()
    $value = isset($array['my_index']) ? $array['my_index'] : '';
    //array_key_exists()
    $value = array_key_exists('my_index', $array) ? $array['my_index'] : '';
    
  2. Konstruksi bahasa list() dapat menghasilkan ini ketika mencoba untuk mengakses indeks array yang tidak ada:

    list($a, $b) = array(0 => 'a');
    //or
    list($one, $two) = explode(',', 'test string');
    

Dua variabel digunakan untuk mengakses dua elemen array, namun hanya ada satu elemen array, index 0, jadi ini akan menghasilkan:

Perhatikan: Pengimbangan tidak terdefinisi: 1

$_POST / $_GET / $_SESSION variabel

Pemberitahuan di atas sering muncul saat bekerja dengan $_POST, $_GET atau $_SESSION. Untuk $_POST dan $_GET Anda hanya perlu memeriksa apakah indeks ada atau tidak sebelum Anda menggunakannya. Untuk $_SESSION Anda harus memastikan bahwa Anda telah memulai sesi session_start() dan bahwa indeks juga ada.

Juga perhatikan bahwa semua 3 variabel superglobals dan huruf besar.

Terkait:


868



Coba ini

Q1: pemberitahuan ini berarti $ varname tidak   didefinisikan pada lingkup saat ini   naskah.

Q2: Penggunaan isset (), empty () condition sebelum menggunakan variabel yang mencurigakan bekerja dengan baik.

// recommended solution for recent PHP versions
$user_name = $_SESSION['user_name'] ?? '';

// pre-7 PHP versions
$user_name = '';
if (!empty($_SESSION['user_name'])) {
     $user_name = $_SESSION['user_name'];
}

Atau, sebagai solusi cepat dan kotor:

// not the best solution, but works
// in your php setting use, it helps hiding site wide notices
error_reporting(E_ALL ^ E_NOTICE);

Catatan tentang sesi:


109



Alternatif (sering berkecil hati) adalah operator penekanan kesalahan  @. Ini adalah konstruksi bahasa khusus untuk menutup pemberitahuan dan peringatan yang tidak diinginkan, tetapi harus digunakan dengan hati-hati.

Pertama, ia menjatuhkan hukuman denda atas penggunaan isset. Itu tidak terukur dalam aplikasi dunia nyata, tetapi harus dipertimbangkan dalam iterasi data yang berat. Kedua mungkin menghambat debugging, tetapi pada saat yang sama kesalahan yang ditekan pada kenyataannya diteruskan ke penangan kesalahan kustom (tidak seperti isset decorated expressions).


46



Ini berarti Anda menguji, mengevaluasi, atau mencetak variabel yang belum Anda tetapkan. Ini berarti Anda salah ketik, atau Anda perlu memeriksa apakah variabel diinisialisasi ke sesuatu terlebih dahulu. Periksa jalur logika Anda, mungkin disetel di satu jalur tetapi tidak di jalur lainnya.


35



Umumnya karena "pemrograman yang buruk", dan kemungkinan untuk kesalahan sekarang atau nanti.

  1. Jika itu kesalahan, buat penugasan yang tepat untuk variabel pertama: $ varname = 0;
  2. Jika itu benar-benar hanya ditentukan kadang-kadang, uji untuk itu: if (isset($varname)), sebelum menggunakannya
  3. Jika itu karena Anda salah mengeja, cukup perbaiki itu
  4. Mungkin bahkan pergantian peringatan di dalam kamu Pengaturan PHP

33



Saya tidak ingin menonaktifkan pemberitahuan karena itu membantu, tetapi ingin menghindari terlalu banyak mengetik.

Solusi saya adalah fungsi ini:

function ifexists($varname)
{
  return(isset($$varname)?$varname:null);
}

Jadi jika saya ingin merujuk ke $ name dan echo jika ada, saya hanya menulis:

<?=ifexists('name')?>

Untuk elemen larik:

function ifexistsidx($var,$index)
{
  return(isset($var[$index])?$var[$index]:null);
}

Di halaman jika saya ingin merujuk ke $ _REQUEST ['name']:

<?=ifexistsidx($_REQUEST,'name')?>

30



Cara terbaik untuk mendapatkan masukan tali aku s:

$value = filter_input(INPUT_POST, 'value');

Satu-liner ini hampir setara dengan:

if (!isset($_POST['value'])) {
    $value = null;
} elseif (is_array($_POST['value'])) {
    $value = false;
} else {
    $value = $_POST['value'];
}

Jika Anda benar-benar menginginkannya tali nilai, seperti:

$value = (string)filter_input(INPUT_POST, 'value');

24



Dalam balasan ke "" Mengapa mereka muncul tiba-tiba? Saya dulu menggunakan skrip ini selama bertahun-tahun dan saya tidak pernah punya masalah. " 

Sangat umum bagi sebagian besar situs untuk beroperasi di bawah pelaporan kesalahan "default" dari "Tampilkan semua kesalahan, tetapi tidak 'pemberitahuan' dan 'tidak berlaku lagi'". Ini akan diatur dalam php.ini dan berlaku untuk semua situs di server. Ini berarti bahwa "pemberitahuan" yang digunakan dalam contoh akan ditekan (disembunyikan) sementara kesalahan lain, yang dianggap lebih penting, akan ditampilkan / direkam.

Pengaturan kritis lainnya adalah kesalahan dapat disembunyikan (mis. display_errors diatur ke "off" atau "syslog").

Apa yang akan terjadi dalam kasus ini adalah bahwa baik error_reporting diubah untuk juga menunjukkan pemberitahuan (sesuai contoh) dan / atau bahwa pengaturan diubah menjadi display_errors di layar (sebagai lawan menekan mereka / penebangan mereka).

Mengapa mereka berubah?

Jawaban yang jelas / paling sederhana adalah bahwa seseorang menyesuaikan salah satu dari pengaturan ini di php.ini, atau versi upgrade PHP sekarang menggunakan php.ini yang berbeda dari sebelumnya. Itu tempat pertama yang harus dilihat.

Namun juga dimungkinkan untuk mengganti pengaturan ini

  • .htconf (konfigurasi server web, termasuk vhosts dan sub-konfigurasi) *
  • .htaccess
  • dalam kode php itu sendiri

dan semua ini juga bisa diubah.

Ada juga komplikasi tambahan bahwa konfigurasi server web dapat mengaktifkan / menonaktifkan .htaccess arahan, jadi jika Anda memiliki arahan dalam .htaccess yang tiba-tiba mulai / berhenti berfungsi maka Anda perlu memeriksa itu.

(.htconf / .htaccess menganggap Anda berjalan sebagai apache. Jika menjalankan baris perintah ini tidak akan berlaku; jika menjalankan IIS atau server web lain maka Anda harus memeriksa konfigurasi tersebut sesuai)

Ringkasan

  • Memeriksa error_reporting dan display_errors direktif php di php.ini tidak berubah, atau Anda tidak menggunakan php.ini yang berbeda dari sebelumnya.
  • Memeriksa error_reporting dan display_errors arahan php di .htconf (atau vhosts dll) tidak berubah
  • Memeriksa error_reporting dan display_errors arahan php di .htaccess tidak berubah
  • Jika Anda memiliki petunjuk di .htaccess, periksa apakah masih diizinkan di file .htconf
  • Akhirnya periksa kode Anda; mungkin perpustakaan yang tidak terkait; untuk melihat jika error_reporting dan display_errors direktif php telah diatur di sana.

24



Ini karena variabel '$ user_location' tidak didefinisikan. Jika Anda menggunakan loop if di mana Anda mendeklarasikan variabel '$ user_location' maka Anda juga harus memiliki loop lain dan menentukan yang sama. Sebagai contoh:

$a=10;
if($a==5) { $user_location='Paris';} else { }
echo $user_location;

Kode di atas akan membuat kesalahan karena jika loop tidak puas dan di loop yang lain '$ user_location' tidak didefinisikan. Masih PHP diminta untuk echo keluar variabel. Jadi untuk memodifikasi kode Anda harus melakukan hal berikut:

$a=10;
if($a==5) { $user_location='Paris';} else { $user_location='SOMETHING OR BLANK'; }
echo $user_location;

23



perbaikan cepat adalah menetapkan variabel Anda ke nol di bagian atas kode Anda

$user_location = null;

16