"Pemberitahuan: Variabel tidak terdefinisi", "Pemberitahuan: Indeks tidak terdefinisi", dan "Pemberitahuan: Undefined offset" menggunakan PHP

1173

Saya menjalankan skrip PHP dan terus menerima kesalahan seperti:

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

Pemberitahuan: Indeks tidak terdefinisi: my_index C: \ wamp \ www \ mypath \ index.php pada baris 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 dari pesan kesalahan ini?

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

Bagaimana cara memperbaikinya?


Ini adalah pertanyaan Referensi Umum bagi orang untuk ditautkan sebagai duplikat, alih-alih harus menjelaskan masalah berulang kali. Saya merasa ini perlu karena sebagian besar jawaban dunia nyata untuk masalah ini sangat spesifik.

Diskusi Meta terkait:

Pekka 웃
sumber
8
kemungkinan rangkap dari Referensi - Apa artinya kesalahan ini dalam PHP?
meagar
3
variabel mungkin belum diinisialisasi. Apakah Anda menginisialisasi variabel dari posting atau dapatkan atau array apa pun? Jika itu masalahnya Anda mungkin tidak memiliki bidang dalam array itu. Itu mengakses Anda.
Anish Silwal
3
@Pekka 웃 - Saya perhatikan suntingan menambahkan "dan" Perhatikan: Offset tidak terdefinisi "" - Bukankah lebih masuk akal menggunakan "PHP:" Variabel tidak terdefinisi "," Indeks tidak terdefinisi "," Pemberitahuan undefined offset "" (bahkan mengambil keluar dari PHP, karena ini ditandai sebagai "php". Plus, URL terputus di and-notice-undef, hanya saran agar URL tidak terpotong. Mungkin bahkan menghapus tanda kutip (terlalu banyak). AtauPHP: “Undefined variable/index/offset” notices
Funk Forty Niner
2
@ Fred Saya kira argumen dapat dibuat untuk kedua variasi. Ada kemungkinan bahwa pemula akan memasuki seluruh baris, termasuk "Pemberitahuan:" ke dalam kueri penelusuran mereka, yang saya yakin adalah penghasil lalu lintas utama untuk pertanyaan ini. Jika pesan ada di sana secara penuh, itu kemungkinan akan meningkatkan visibilitas di mesin pencari
Pekka
2
@ Pekka 웃 Saya mengerti. Saya hanya mengatakan itu karena URL tidak terpotong sebelumnya dan sekarang tidak di and-notice-undef. Itu hanya (beberapa) saran. Itu hanya mengulangi dirinya juga Notice: Undefined.
Funk Forty Niner

Jawaban:

1066

Perhatikan: Variabel tidak terdefinisi

Dari kebijaksanaan PHP Manual yang luas :

Mengandalkan nilai default variabel tidak diinisialisasi bermasalah dalam kasus termasuk satu file ke yang lain yang menggunakan nama variabel yang sama. Ini juga merupakan risiko keamanan utama dengan register_globals dihidupkan. Kesalahan tingkat E_NOTICE dikeluarkan jika bekerja dengan variabel yang tidak diinisialisasi, namun tidak dalam hal menambahkan elemen ke array yang tidak diinisialisasi. konstruksi bahasa isset () dapat digunakan untuk mendeteksi jika suatu variabel telah diinisialisasi. Selain itu dan yang 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 setara dengan ! Isset ($ var) || $ var == false .

Ini berarti bahwa Anda bisa menggunakan hanya empty()untuk menentukan apakah variabel diatur, dan di samping itu memeriksa variabel terhadap berikut, 0, 0.0, "", "0", null, falseatau [].

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 editor PHP online 3v4l.org

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

Cara menangani masalah ini:

  1. Disarankan: Nyatakan variabel Anda, misalnya saat Anda mencoba menambahkan string ke variabel yang tidak ditentukan. Atau gunakan isset()/ !empty() untuk memeriksa apakah mereka dinyatakan sebelum merujuk mereka, seperti pada:

    //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 pada PHP 7.0, sekarang Anda dapat menggunakan operator null coalesce :

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. Tetapkan penangan kesalahan khusus untuk E_NOTICE dan arahkan pesan menjauh 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 adil E_NOTICEadalah:

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

Catatan: Sangat disarankan untuk mengimplementasikan poin 1 saja.

Pemberitahuan: Indeks tidak terdefinisi / Offset tidak terdefinisi

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

Cara menangani masalah ini:

  1. Periksa apakah indeks ada sebelum Anda mengaksesnya. Untuk ini, Anda dapat menggunakan 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. Konstruk bahasa list()dapat menghasilkan ini ketika mencoba 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, indeks 0, jadi ini akan menghasilkan:

Pemberitahuan: Offset yang tidak ditentukan: 1

$_POST/ $_GET/ $_SESSIONVariabel

Pemberitahuan di atas sering muncul saat bekerja dengan $_POST, $_GETatau $_SESSION. Untuk $_POSTdan $_GETAnda hanya perlu memeriksa apakah indeks ada atau tidak sebelum Anda menggunakannya. Untuk $_SESSIONAnda harus memastikan Anda memiliki sesi dimulai session_start()dan indeks juga ada.

Juga perhatikan bahwa ketiga variabel adalah superglobals dan huruf besar.

Terkait:

Rizier123
sumber
7
@ dieselpower44 Beberapa pemikiran: "operator shut-up" ( @) memiliki beberapa masalah kinerja. Selain itu, karena menekan semua kesalahan dalam lingkup tertentu, menggunakannya tanpa perawatan mungkin menutupi pesan yang ingin Anda lihat.
IMSoP
6
Menyembunyikan masalah BUKAN cara untuk menangani masalah. Item # 2 ... # 4 hanya dapat digunakan di server produksi, tidak secara umum.
Salman A
1
Apakah mungkin untuk mem-shutdown pesan inline (tidak di handler) ketika juga handler error custom digunakan? $var = @$_GET['nonexisting'];masih menyebabkan pemberitahuan ..
Alph.Dev
18
Mengapa disarankan untuk menggunakan 1. $value = isset($_POST['value']) ? $_POST['value'] : '';alih-alih menggunakan 4. $value = @$_POST['value'];?
forsvunnet
@twistedpixel 4 cara itu independen, itu bukan panduan 4 langkah. Jadi jika Anda memilih untuk menggunakan cara 4, itu berarti Anda belum menerapkan 3 cara pertama, jadi Anda belum menekan kesalahan apa pun.
Aycan Yaşıt
141

Coba ini

T1: pemberitahuan ini berarti $ varname tidak didefinisikan pada skrip saat ini.

T2: Penggunaan kondisi isset (), kosong () sebelum menggunakan variabel yang mencurigakan berfungsi 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:

Ish
sumber
Jika menggunakan E_NOTICEdari php.inifile konfigurasi, lakukanerror_reporting = (E_ALL & ~E_NOTICE)
ahmd0
Dari jawaban di atas, saya telah mencoba isset, array_key_exists tetapi itu tidak berhasil. Saya mencoba jawaban Anda, .tyty (), dan berhasil. Terima kasih banyak!
ewef
63

Operator tampilan kesalahan@

Untuk pemberitahuan yang tidak diinginkan dan berlebihan, seseorang dapat menggunakan @operator khusus untuk » menyembunyikan « pesan variabel / indeks yang tidak ditentukan.

$var = @($_GET["optional_param"]);
  • Ini biasanya tidak dianjurkan. Pendatang baru cenderung menggunakannya secara berlebihan.
  • Sangat tidak pantas untuk kode jauh di dalam logika aplikasi (mengabaikan variabel yang tidak dideklarasikan di tempat yang seharusnya tidak Anda), misalnya untuk parameter fungsi, atau dalam loop.
  • Ada satu terbalik di atas isset?:atau ??super-supression namun. Pemberitahuan masih bisa dicatat. Dan seseorang dapat membangkitkan @pemberitahuan yang disembunyikan dengan:set_error_handler("var_dump");
    • Selain itu Anda tidak boleh terbiasa menggunakan / merekomendasikan if (isset($_POST["shubmit"]))dalam kode awal Anda.
    • Pendatang baru tidak akan menemukan kesalahan ketik seperti itu. Itu hanya membuat Anda kehilangan Pemberitahuan PHP untuk kasus-kasus itu. Tambahkan @atau issethanya setelah memverifikasi fungsionalitas.
    • Perbaiki penyebabnya terlebih dahulu. Bukan pemberitahuan.

  • @terutama untuk $_GET/ $_POSTparameter input, khususnya jika mereka opsional .

Dan karena ini mencakup sebagian besar pertanyaan seperti itu, mari kita bahas penyebab paling umum:

$_GET/ $_POST/ $_REQUESTinput yang tidak ditentukan

  • Hal pertama yang Anda lakukan ketika menemukan indeks / offset tidak terdefinisi, adalah memeriksa salah ketik:
    $count = $_GET["whatnow?"];

    • Apakah ini nama kunci yang diharapkan dan ada pada setiap permintaan halaman?
    • Nama variabel dan indeks array peka huruf besar-kecil di PHP.
  • Kedua, jika pemberitahuan tersebut tidak memiliki penyebab yang jelas, gunakan var_dumpatau print_runtuk memverifikasi semua array input untuk konten saat ini:

    var_dump($_GET);
    var_dump($_POST);
    //print_r($_REQUEST);
    

    Keduanya akan mengungkapkan jika skrip Anda dipanggil dengan benar atau parameter apa pun.

  • Alternatif atau gunakan devtools browserF12 Anda ( ) dan periksa tab jaringan untuk permintaan dan parameter:

    alat pengembang browser / tab jaringan

    Parameter POST dan input GET akan ditampilkan secara terpisah.

  • Untuk $_GETparameter Anda juga dapat mengintip di QUERY_STRINGdalam

    print_r($_SERVER);

    PHP memiliki beberapa aturan untuk menyatukan nama parameter non-standar ke dalam superglobals. Apache mungkin juga menulis ulang. Anda juga dapat melihat $_COOKIESheader permintaan HTTP mentah dan lainnya yang disediakan dengan cara itu.

  • Secara lebih jelas lihat bilah alamat peramban Anda untuk parameter GET :

    http://example.org/script.php?id=5&sort=desc

    The name=valuepasang setelah ?tanda tanya adalah parameter Anda query (GET). Dengan demikian URL ini hanya dapat menghasilkan $_GET["id"]dan $_GET["sort"].

  • Akhirnya periksa <form>dan<input> deklarasi Anda, jika Anda mengharapkan parameter tetapi tidak menerima.

    • Pastikan setiap input yang dibutuhkan memiliki <input name=FOO>
    • The id=atau title=atribut tidak cukup.
    • Suatu method=POSTbentuk harus diisi $_POST.
    • Sedangkan a method=GET(atau meninggalkannya) akan menghasilkan $_GETvariabel.
    • Dimungkinkan juga untuk menyediakan formulir action=script.php?get=parammelalui $ _GET dan method=POSTbidang lainnya dalam $ _POST di samping.
    • Dengan konfigurasi PHP modern (≥ 5.6) menjadi layak (tidak modis) untuk digunakan $_REQUEST['vars']lagi, yang membuat parets GET dan POST meningkat.
  • Jika Anda menggunakan mod_rewrite, maka Anda harus memeriksa keduanya access.logdan mengaktifkannya RewriteLoguntuk mengetahui parameter yang tidak ada.

$_FILES

  • Cek kewarasan yang sama berlaku untuk mengunggah file dan $_FILES["formname"].
  • Apalagi periksa enctype=multipart/form-data
  • Serta method=POSTdalam <form>deklarasi Anda .
  • Lihat juga: PHP Undefined index error $ _FILES?

$_COOKIE

  • The $_COOKIEarray tidak pernah dihuni tepat setelah setcookie(), tetapi hanya pada setiap permintaan ikutan HTTP.
  • Selain itu validitas waktu mereka habis, mereka dapat menjadi kendala untuk subdomain atau jalur individu, dan pengguna dan browser dapat menolak atau menghapusnya.
mario
sumber
2
Jika Anda ingin tahu apa dampak kinerja, artikel ini merangkumnya dengan baik, derickrethans.nl/… .
Gajus
@GajusKuizinas Telah ada beberapa perubahan sejak 2009, khususnya php.net/ChangeLog-5.php#5.4.0 mengubah hasilnya secara drastis (lihat "Mesin Zend, kinerja" dan "operator (diam)").
mario
Terima kasih @mario, menarik. Sekarang, jika seseorang cukup baik untuk membandingkan keduanya ... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs Menurut tes ini, tampaknya identik (perhatikan bahwa perubahan skala).
Gajus
47

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

  1. Jika itu kesalahan, buatlah tugas yang tepat untuk variabel terlebih dahulu: $ varname = 0;
  2. Jika benar-benar hanya didefinisikan kadang-kadang, uji untuk itu:, if (isset($varname))sebelum menggunakannya
  3. Jika itu karena Anda salah mengeja, perbaiki saja
  4. Mungkin bahkan pergantian peringatan di pengaturan PHP Anda
Erik
sumber
5
Tolong jangan mematikan peringatan. Dalam bahasa yang lebih ketat, mereka sering berarti "mungkin ada bug, Anda sebaiknya memeriksa baris ini dua kali" - dalam bahasa yang permisif seperti PHP, mereka sering berarti "kode ini omong kosong dan secara proporsional penuh dengan bug; Saya akan mencoba untuk membuat beberapa rasa tetapi Anda lebih baik memperbaiki ASAP ini ".
5
Meskipun saya setuju dengan tiga poin pertama, # 4 sama sekali salah. Menyembunyikan masalah tidak akan membuatnya hilang, dan bahkan mungkin menyebabkan lebih banyak masalah di jalan.
Valentin Flachsel
1
@Freek benar-benar benar, tetapi dalam beberapa skenario (Skrip dibeli, tanpa pengetahuan teknis, perlu dijalankan besok ...) itu solusi lakban - benar-benar buruk, yang selalu perlu ditekankan, tetapi pilihan
Pekka
Lakban bagus ... kadang-kadang. Secara historis, peringatan telah diubah dalam pengaturan PHP standar, tetapi pengaturan yang salah telah menjadi lebih ketat. Sayang sekali banyak yang kembali ke pengaturan lama, agar tidak mengganggu pelanggan.
Erik
41

Ini berarti Anda sedang menguji, mengevaluasi, atau mencetak variabel yang belum Anda tetapkan. Itu berarti Anda memiliki salah ketik, atau Anda perlu memeriksa bahwa variabel diinisialisasi ke sesuatu terlebih dahulu. Periksa jalur logika Anda, itu mungkin diatur dalam satu jalur tetapi tidak di jalur lain.

DGM
sumber
34

Saya tidak ingin menonaktifkan pemberitahuan karena ini 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 cukup menulis:

<?=ifexists('name')?>

Untuk elemen array:

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

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

<?=ifexistsidx($_REQUEST,'name')?>
Ferenci Zoltán László
sumber
2
Fungsi ifexists () Anda tidak berfungsi untuk saya di PHP 5.3. Variabel penelepon tidak tersedia dalam lingkup lokal fungsi (lihat lingkup Variabel ), kecuali jika itu Superglobals atau Anda mengutak-atik $ GLOBALS , sehingga $foo = "BABAR"; ifexists('foo');secara umum akan mengembalikan nol. (Italia adalah bab-bab php.net.)
skierpage
sekarang Anda akan mendapatkan "halo dari" ... apa gunanya? cukup periksa nilainyaif( !empty($user) and !empty($location) ) echo "hello $user ..."
gcb
27

Cara terbaik untuk mendapatkan string input adalah:

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

Lapisan satu 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 menginginkan nilai string , seperti:

$value = (string)filter_input(INPUT_POST, 'value');
mpyw
sumber
25

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

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

Kode di atas akan membuat kesalahan karena The if loop tidak puas dan di loop lain '$ user_location' tidak didefinisikan. PHP masih diminta untuk mengulangi 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;
Roger
sumber
25

Sebagai balasan untuk "" Mengapa mereka muncul tiba-tiba? Saya biasa 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 bukan 'pemberitahuan' dan 'usang'". 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 lainnya, yang dianggap lebih kritis, akan ditampilkan / direkam.

Pengaturan penting lainnya adalah kesalahan dapat disembunyikan (yaitu display_errorsdiatur ke "off" atau "syslog").

Apa yang akan terjadi dalam kasus ini adalah bahwa baik error_reportingitu diubah untuk juga menampilkan pemberitahuan (sesuai contoh) dan / atau bahwa pengaturan diubah ke display_errorspada layar (sebagai lawan untuk menekan mereka / login mereka).

Mengapa mereka berubah?

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

Namun dimungkinkan juga untuk mengabaikan pengaturan ini di

  • .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 arahan .htaccess, jadi jika Anda memiliki arahan dalam .htaccess yang tiba-tiba mulai / berhenti berfungsi maka Anda perlu memeriksa itu.

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

Ringkasan

  • Periksa error_reportingdan display_errorsarahan php di php.ini belum berubah, atau Anda tidak menggunakan php.ini yang berbeda dari sebelumnya.
  • Periksa error_reportingdan display_errorsarahan php dalam .htconf (atau vhosts dll) belum berubah
  • Periksa error_reportingdan display_errorsarahan php dalam .htaccess belum berubah
  • Jika Anda memiliki arahan dalam .htaccess, periksa apakah masih diizinkan dalam file .htconf
  • Akhirnya periksa kode Anda; mungkin perpustakaan yang tidak terkait; untuk melihat apakah error_reportingdan display_errorsarahan php telah ditetapkan di sana.
Robbie
sumber
20

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

$user_location = null;
Shahin Mammadzada
sumber
16

Saya dulu mengutuk kesalahan ini, tetapi bisa mengingatkan Anda untuk melarikan diri dari input pengguna.

Misalnya, jika Anda pikir ini cerdas, kode singkatan:

// Echo whatever the hell this is
<?=$_POST['something']?>

...Pikirkan lagi! Solusi yang lebih baik adalah:

// If this is set, echo a filtered version
<?=isset($_POST['something']) ? html($_POST['something']) : ''?>

(Saya menggunakan html()fungsi khusus untuk keluar dari karakter, jarak tempuh Anda mungkin beragam)

rybo111
sumber
15

Di PHP 7.0 sekarang mungkin menggunakan operator penggabungan Null:

echo "My index value is: " . ($my_array["my_index"] ?? '');

Sama dengan:

echo "My index value is: " . (isset($my_array["my_index"]) ? $my_array["my_index"] : '');

Manual PHP PHP 7.0

elpiel
sumber
Ini juga berfungsi dengan baik dalam pernyataan if. if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
seorang coder
Kode Anda sebenarnya adalah bug yang diabaikan: ?? - hanya memeriksa isset(), jika Anda lulus is_array()- yang merupakan boolean, perilaku tak terduga akan mengikuti.
elpiel
14

Saya menggunakan semua fungsi exst () yang berguna yang secara otomatis mendeklarasikan variabel.

Kode Anda akan -

$greeting = "Hello, ".exst($user_name, 'Visitor')." from ".exst($user_location);


/** 
 * Function exst() - Checks if the variable has been set 
 * (copy/paste it in any place of your code)
 * 
 * If the variable is set and not empty returns the variable (no transformation)
 * If the variable is not set or empty, returns the $default value
 *
 * @param  mixed $var
 * @param  mixed $default
 * 
 * @return mixed 
 */

function exst( & $var, $default = "")
{
    $t = "";
    if ( !isset($var)  || !$var ) {
        if (isset($default) && $default != "") $t = $default;
    }
    else  {  
        $t = $var;
    }
    if (is_string($t)) $t = trim($t);
    return $t;
}
user2253362
sumber
14

Dalam Bahasa yang sangat Sederhana .
Kesalahannya adalah Anda menggunakan variabel $user_locationyang tidak Anda tetapkan sebelumnya dan tidak memiliki nilai. Jadi saya sarankan Anda untuk mendeklarasikan variabel ini sebelum menggunakannya , Sebagai contoh:


$user_location = '';
Atau
$user_location = 'Los Angles';
Ini adalah kesalahan yang sangat umum yang bisa Anda hadapi. Jadi jangan khawatir hanya mendeklarasikan variabel dan Nikmati Pengkodean .

Rishabh Seth
sumber
8

mengapa tidak membuat hal-hal sederhana?

<?php
error_reporting(E_ALL); // making sure all notices are on

function idxVal(&$var, $default = null) {
         return empty($var) ? $var = $default : $var;
  }

echo idxVal($arr['test']);         // returns null without any notice
echo idxVal($arr['hey ho'], 'yo'); // returns yo and assigns it to array index, nice

?>
gts
sumber
8

MENGAPA INI TERJADI?

Seiring waktu, PHP telah menjadi bahasa yang lebih fokus pada keamanan. Pengaturan yang dulu dimatikan secara default sekarang dihidupkan secara default. Contoh sempurna untuk ini adalah E_STRICT, yang dinyalakan secara default pada PHP 5.4.0 .

Selanjutnya, menurut dokumentasi PHP, secara default, E_NOTICEdinonaktifkan di php.ini. PHP docs merekomendasikan menyalakannya untuk keperluan debugging . Namun, ketika saya mengunduh PHP dari repositori Ubuntu dan dari tumpukan Windows BitNami, saya melihat sesuatu yang lain.

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

Perhatikan bahwa error_reportingsebenarnya diatur ke nilai produksi secara default, bukan ke nilai "default" secara default. Ini agak membingungkan dan tidak didokumentasikan di luar php.ini, jadi saya belum memvalidasi ini pada distribusi lain.

Namun, untuk menjawab pertanyaan Anda, kesalahan ini muncul saat tidak muncul sebelumnya karena:

  1. Anda menginstal PHP dan pengaturan default baru agak kurang didokumentasikan tetapi tidak mengecualikan E_NOTICE.

  2. E_NOTICEperingatan seperti variabel yang tidak ditentukan dan indeks yang tidak ditentukan sebenarnya membantu membuat kode Anda lebih bersih dan lebih aman. Saya dapat memberitahu Anda bahwa, bertahun-tahun yang lalu, dengan E_NOTICEmengaktifkan terus memaksa saya untuk mendeklarasikan variabel saya. Itu membuatnya BANYAK lebih mudah untuk belajar C, tidak menyatakan variabel jauh lebih besar dari gangguan.

APA YANG BISA SAYA LAKUKAN TENTANG ITU?

  1. Matikan E_NOTICEdengan menyalin "Nilai default" E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATEDdan menggantinya dengan apa yang saat ini dihapus komentar setelah sama dengan masuk error_reporting =. Mulai ulang Apache, atau PHP jika menggunakan CGI atau FPM. Pastikan Anda mengedit "benar" php.ini. Yang benar adalah Apache jika Anda menjalankan PHP dengan Apache, fpm atau php-fpm jika menjalankan PHP-FPM, cgi jika menjalankan PHP-CGI, dll. Ini bukan metode yang disarankan, tetapi jika Anda memiliki kode lawas yang akan menjadi sangat sulit untuk diedit, maka itu mungkin taruhan terbaik Anda.

  2. Matikan E_NOTICElevel file atau folder. Ini mungkin lebih disukai jika Anda memiliki beberapa kode lama tetapi ingin melakukan hal-hal dengan cara yang "benar" sebaliknya. Untuk melakukan ini, Anda harus berkonsultasi dengan Apache2, Nginx, atau apa pun server pilihan Anda. Di Apache, Anda akan menggunakan php_valuebagian dalam <Directory>.

  3. Tulis ulang kode Anda menjadi lebih bersih. Jika Anda perlu melakukan ini saat pindah ke lingkungan produksi atau tidak ingin seseorang melihat kesalahan Anda, pastikan Anda menonaktifkan tampilan kesalahan apa pun, dan hanya mencatat kesalahan Anda (lihat display_errorsdan log_errorsdi php.ini dan pengaturan server Anda) .

Untuk memperluas opsi 3: Ini adalah yang ideal. Jika Anda dapat menempuh rute ini, Anda harus melakukannya. Jika Anda tidak memulai rute ini pada awalnya, pertimbangkan untuk memindahkan rute ini pada akhirnya dengan menguji kode Anda di lingkungan pengembangan. Sementara Anda berada di sana, singkirkan ~E_STRICTdan ~E_DEPRECATEDlihat apa yang salah di masa depan. Anda akan melihat BANYAK kesalahan yang tidak dikenal, tetapi itu akan menghentikan Anda dari memiliki masalah yang tidak menyenangkan ketika Anda perlu meningkatkan PHP di masa depan.

APA ARTINYA KESALAHAN?

Undefined variable: my_variable_name- Ini terjadi ketika variabel belum didefinisikan sebelum digunakan. Ketika skrip PHP dieksekusi, secara internal hanya mengasumsikan nilai nol. Namun, dalam skenario mana Anda perlu memeriksa variabel sebelum didefinisikan? Pada akhirnya, ini adalah argumen untuk "kode ceroboh". Sebagai seorang pengembang, saya dapat memberitahu Anda bahwa saya menyukainya ketika saya melihat proyek open source di mana variabel didefinisikan sebagai tinggi dalam cakupan mereka karena mereka dapat didefinisikan. Itu membuatnya lebih mudah untuk mengetahui variabel apa yang akan muncul di masa depan dan membuatnya lebih mudah untuk membaca / mempelajari kode.

function foo()
{
    $my_variable_name = '';

    //....

    if ($my_variable_name) {
        // perform some logic
    }
}

Undefined index: my_index- Ini terjadi ketika Anda mencoba mengakses nilai dalam array dan itu tidak ada. Untuk mencegah kesalahan ini, lakukan pemeriksaan bersyarat.

// verbose way - generally better
if (isset($my_array['my_index'])) {
    echo "My index value is: " . $my_array['my_index'];
}

// non-verbose ternary example - I use this sometimes for small rules.
$my_index_val = isset($my_array['my_index'])?$my_array['my_index']:'(undefined)';
echo "My index value is: " . $my_index_val;   

Pilihan lain adalah mendeklarasikan array kosong di bagian atas fungsi Anda. Ini tidak selalu memungkinkan.

$my_array = array(
    'my_index' => ''
);

//...

$my_array['my_index'] = 'new string';

(tip tambahan)

  • Ketika saya menghadapi masalah ini dan lainnya, saya menggunakan NetBeans IDE (gratis) dan memberi saya sejumlah peringatan dan pemberitahuan. Beberapa dari mereka menawarkan tips yang sangat membantu. Ini bukan persyaratan, dan saya tidak menggunakan IDE lagi kecuali untuk proyek-proyek besar. Saya lebih dari vimorang hari ini :).
smcjones
sumber
6

indeks undefined berarti dalam array yang Anda minta untuk indeks array yang tidak tersedia misalnya

<?php 

$newArray[] = {1,2,3,4,5};
print_r($newArray[5]);

?>

variabel tidak terdefinisi berarti Anda telah menggunakan sepenuhnya bukan variabel yang ada atau yang tidak didefinisikan atau diinisialisasi dengan nama itu misalnya

<?php print_r($myvar); ?>

berarti offset yang didefinisikan dalam array yang Anda minta tidak ada kunci. Dan solusi untuk ini adalah memeriksa sebelum digunakan

php> echo array_key_exists(1, $myarray);
Sintayehu Abaynhe
sumber
4

Mengenai bagian pertanyaan ini:

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

Tidak ada jawaban yang pasti tetapi berikut adalah beberapa kemungkinan penjelasan mengapa pengaturan dapat 'tiba-tiba' berubah:

  1. Anda telah memutakhirkan PHP ke versi yang lebih baru yang dapat memiliki default lain untuk error_reporting, display_errors atau pengaturan lain yang relevan.

  2. Anda telah menghapus atau memperkenalkan beberapa kode (mungkin dalam ketergantungan) yang menetapkan pengaturan yang relevan saat runtime menggunakan ini_set()atau error_reporting()(cari ini dalam kode)

  3. Anda mengubah konfigurasi server web (dengan asumsi apache di sini): .htaccesskonfigurasi file dan vhost juga dapat memanipulasi pengaturan php.

  4. Biasanya pemberitahuan tidak ditampilkan / dilaporkan (lihat manual PHP ) sehingga ada kemungkinan bahwa ketika menyiapkan server, file php.ini tidak dapat dimuat karena suatu alasan (izin file ??) dan Anda berada di pengaturan default . Kemudian, 'bug' telah diselesaikan (secara tidak sengaja) dan sekarang BISA memuat file php.ini yang benar dengan set error_reporting untuk menampilkan pemberitahuan.

Wouter de Winter
sumber
3

Jika bekerja dengan kelas, Anda perlu memastikan Anda merujuk variabel anggota menggunakan $this:

class Person
{
    protected $firstName;
    protected $lastName;

    public function setFullName($first, $last)
    {
        // Correct
        $this->firstName = $first;

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}
John Conde
sumber
3

Alasan lain mengapa pemberitahuan indeks yang tidak ditentukan akan dilempar, adalah bahwa kolom dihilangkan dari permintaan basis data.

Yaitu:

$query = "SELECT col1 FROM table WHERE col_x = ?";

Kemudian mencoba mengakses lebih banyak kolom / baris di dalam satu lingkaran.

Yaitu:

print_r($row['col1']);
print_r($row['col2']); // undefined index thrown

atau dalam satu whilelingkaran:

while( $row = fetching_function($query) ) {

    echo $row['col1'];
    echo "<br>";
    echo $row['col2']; // undefined index thrown
    echo "<br>";
    echo $row['col3']; // undefined index thrown

}

Hal lain yang perlu dicatat adalah bahwa pada * NIX OS dan Mac OS X, semuanya sensitif huruf besar-kecil.

Konsultasikan Tanya Jawab berikut tentang di Stack:

Fred -ii-
sumber
3

Menggunakan terner sederhana, mudah dibaca, dan bersih:

Pra PHP 7
Tetapkan variabel ke nilai variabel lain jika disetel, tetapkan lainnull(ataunilai default apa pun yangAnda butuhkan):

$newVariable = isset($thePotentialData) ? $thePotentialData : null;

PHP 7+
Sama kecuali menggunakan Null Coalescing Operator . Tidak ada lagi kebutuhan untuk memanggil isset()karena ini dibangun, dan tidak perlu memberikan variabel untuk kembali karena diasumsikan mengembalikan nilai variabel yang diperiksa:

$newVariable = $thePotentialData ?? null;

Keduanya akan menghentikan Pemberitahuan dari pertanyaan OP, dan keduanya sama persis dengan:

if (isset($thePotentialData)) {
    $newVariable = $thePotentialData;
} else {
    $newVariable = null;
}

 
Jika Anda tidak memerlukan pengaturan variabel baru maka Anda dapat langsung menggunakan nilai yang dikembalikan ternary, seperti dengan echo, argumen fungsi, dll:

Gema:

echo 'Your name is: ' . isset($name) ? $name : 'You did not provide one';

Fungsi:

$foreName = getForeName(isset($userId) ? $userId : null);

function getForeName($userId)
{
    if ($userId === null) {
        // Etc
    }
}

Di atas akan bekerja sama dengan array, termasuk sesi, dll, menggantikan variabel yang diperiksa dengan misalnya:
$_SESSION['checkMe']
atau seberapa banyak level yang Anda butuhkan, misalnya:
$clients['personal']['address']['postcode']


 

Penekanan:

Dimungkinkan untuk menekan Pemberitahuan PHP dengan @atau mengurangi tingkat pelaporan kesalahan Anda, tetapi itu tidak memperbaiki masalah , itu hanya menghentikannya dilaporkan dalam log kesalahan. Ini berarti bahwa kode Anda masih mencoba menggunakan variabel yang tidak disetel, yang mungkin atau mungkin tidak berarti sesuatu tidak berfungsi sebagaimana dimaksud - tergantung pada seberapa penting nilai yang hilang itu.

Anda harus benar-benar memeriksa masalah ini dan menanganinya dengan tepat, baik menyajikan pesan yang berbeda, atau bahkan hanya mengembalikan nilai nol untuk segala sesuatu yang lain untuk mengidentifikasi keadaan yang tepat.

Jika Anda hanya peduli tentang Pemberitahuan tidak ada di log kesalahan, maka sebagai opsi Anda bisa mengabaikan log kesalahan.

James
sumber
1

Salah satu penyebab umum dari variabel tidak ada setelah formulir HTML dikirimkan adalah elemen formulir tidak ada di dalam <form>tag:

Contoh: Elemen tidak terkandung di dalam <form>

<form action="example.php" method="post">
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>

<select name="choice">
    <option value="choice1">choice 1</option>
    <option value="choice2">choice 2</option>
    <option value="choice3">choice 3</option>
    <option value="choice4">choice 4</option>
</select>

Contoh: Elemen sekarang terkandung dalam <form>

<form action="example.php" method="post">
    <select name="choice">
        <option value="choice1">choice 1</option>
        <option value="choice2">choice 2</option>
        <option value="choice3">choice 3</option>
        <option value="choice4">choice 4</option>
    </select>
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>
John Conde
sumber
0

Mungkin Anda menggunakan versi PHP lama sampai dan sekarang memutakhirkan PHP itulah alasannya ia bekerja tanpa kesalahan hingga sekarang dari tahun ke tahun. sampai PHP4 tidak ada kesalahan jika Anda menggunakan variabel tanpa mendefinisikannya tetapi pada PHP5 dan seterusnya ia melempar kesalahan untuk kode seperti yang disebutkan dalam pertanyaan.

fitnah
sumber
0

Saat berurusan dengan file, enctype yang tepat dan metode POST diperlukan, yang akan memicu pemberitahuan indeks yang tidak ditentukan jika salah satu tidak termasuk dalam formulir.

Manual menyatakan sintaks dasar berikut:

HTML

<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

PHP

<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";

?>

Referensi:

Funk Forty Niner
sumber
0

Saya mengajukan pertanyaan tentang ini dan saya dirujuk ke pos ini dengan pesan:

Pertanyaan ini sudah ada jawabannya di sini:

"Pemberitahuan: Variabel tidak terdefinisi", "Pemberitahuan: Indeks tidak terdefinisi", dan "Pemberitahuan: Undefined offset" menggunakan PHP

Saya membagikan pertanyaan dan solusi saya di sini:

Ini kesalahannya:

masukkan deskripsi gambar di sini

Jalur 154 adalah masalahnya. Inilah yang saya miliki di baris 154:

153    foreach($cities as $key => $city){
154        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){

Saya pikir masalahnya adalah bahwa saya menulis jika kondisi untuk variabel $city, yang bukan kunci tetapi nilai dalam $key => $city. Pertama, bisakah Anda mengkonfirmasi jika itu adalah penyebab peringatan? Kedua, jika itu masalahnya, mengapa saya tidak bisa menulis kondisi berdasarkan nilainya? Apakah harus dengan kunci yang saya butuhkan untuk menulis kondisi?

UPDATE 1: Masalahnya adalah ketika mengeksekusi $citiesCounterArray[$key], kadang-kadang $keysesuai dengan kunci yang tidak ada dalam $citiesCounterArrayarray, tetapi itu tidak selalu terjadi berdasarkan data dari loop saya. Yang saya butuhkan adalah mengatur kondisi sehingga jika $keyada dalam array, kemudian jalankan kode, jika tidak, lewati saja.

UPDATE 2: Ini adalah bagaimana saya memperbaikinya dengan menggunakan array_key_exists():

foreach($cities as $key => $city){
    if(array_key_exists($key, $citiesCounterArray)){
        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){
Jaime Montoya
sumber
0

Kesalahan ini terjadi setiap kali kita menggunakan variabel yang tidak disetel.

Cara terbaik untuk menghadapinya adalah mengatur pelaporan kesalahan saat pengembangan.

Untuk mengatur pelaporan kesalahan pada:

ini_set('error_reporting', 'on');
ini_set('display_errors', 'on');
error_reporting(E_ALL);

Pada server produksi, pelaporan kesalahan tidak aktif, oleh karena itu, kami tidak mendapatkan kesalahan ini.

Namun, pada server pengembangan, kami dapat mengatur pelaporan kesalahan.

Untuk menghilangkan kesalahan ini, kita melihat contoh berikut:

if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

Kita dapat menginisialisasi variabel NULLsebelum menetapkan nilainya atau menggunakannya.

Jadi, kita dapat memodifikasi kode sebagai:

$test = NULL;
if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

Ini tidak akan mengganggu logika program apa pun dan tidak akan menghasilkan Pemberitahuan meskipun $testtidak memiliki nilai.

Jadi, pada dasarnya, selalu lebih baik untuk mengatur pelaporan kesalahan ON untuk pengembangan.

Dan perbaiki semua kesalahan.

Dan saat produksi, pelaporan kesalahan harus dinonaktifkan.

Murid
sumber
-1

Pemberitahuan itu karena Anda tidak memiliki variabel yang digunakan defineddan my_indexkunci tidak hadir ke dalam $my_arrayvariabel.

Pemberitahuan itu dipicu setiap saat, karena Anda codetidak benar, tetapi mungkin Anda tidak mengaktifkan pelaporan pemberitahuan.

Selesaikan bug:

$my_variable_name = "Variable name"; // defining variable
echo "My variable value is: " . $my_variable_name;

if(isset($my_array["my_index"])){
    echo "My index value is: " . $my_array["my_index"]; // check if my_index is set 
}

Cara lain untuk mengeluarkan ini:

ini_set("error_reporting", false)
Andrei Todorut
sumber
-2

Di PHP Anda perlu kepalan untuk mendefinisikan variabel setelah itu Anda dapat menggunakannya.
Kita dapat memeriksa variabel didefinisikan atau tidak dengan cara yang sangat efisien !.

//If you only want to check variable has value and value has true and false value.
//But variable must be defined first.

if($my_variable_name){

}

//If you want to check variable is define or undefine
//Isset() does not check that variable has true or false value
//But it check null value of variable
if(isset($my_variable_name)){

}

Penjelasan Sederhana

//It will work with :- true,false,NULL
$defineVarialbe = false;
if($defineVarialbe){
    echo "true";
}else{
    echo "false";
}

//It will check variable is define or not and variable has null value.
if(isset($unDefineVarialbe)){
    echo "true";
}else{
    echo "false";
}
Manish Goswami
sumber