PHP kullanarak “Uyarı: Tanımsız değişken”, “Uyarı: Tanımsız dizin” ve “Uyarı: Tanımsız ofset”


1173

Bir PHP betiği çalıştırıyorum ve aşağıdaki gibi hataları almaya devam ediyorum:

Uyarı: Tanımsız değişken: C: \ wamp \ www \ mypath \ index.php dosyasındaki 10 numaralı değişkenim

Uyarı: Tanımsız dizin: my_index C: \ wamp \ www \ mypath \ index.php on line

10. ve 11. satır şu şekilde görünür:

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

Bu hata mesajlarının anlamı nedir?

Neden aniden ortaya çıkıyorlar? Bu senaryoyu yıllarca kullanıyordum ve hiç problem yaşamadım.

Onları nasıl düzeltirim?


Bu, sorunu tekrar tekrar açıklamak yerine, insanların yinelenen olarak bağlantı vermeleri için Genel Referans sorusudur . Bunun gerekli olduğunu düşünüyorum, çünkü bu konudaki gerçek dünyadaki cevapların çoğu çok spesifik.

İlgili Meta tartışması:



3
değişken başlatılmamış olabilir. Değişkeni bir gönderi veya get veya herhangi bir diziden mi başlatıyorsunuz? Bu durumda, o dizide bir alanınız olmayabilir. Sizin erişiminiz.
Anish Silwal

3
@Pekka 웃 - "ve" Uyarı: Tanımsız ofset "" ekleyerek düzenlemenin farkına vardım - "PHP:" Tanımsız değişken "," Tanımsız dizin "," Tanımsız ofset "bildirimleri" ile daha anlamlı olmaz mı? . o "php" Artı olarak etiketlenmiş beri PHP üzerinden, URL de kesilmiş olur and-notice-undef. hatta belki (çok fazla) tırnak çıkarmadan URL kesilmiş almaz böylece sadece bir öneri, Or.PHP: “Undefined variable/index/offset” notices
Funk Forty Niner

2
@Fred Her iki varyasyon için bir argüman yapılabilir sanırım. Yeni başlayanlar arama sorusuna "Uyarı:" dahil olmak üzere tüm satır girmesi için bir şans var, eminim bu sorunun ana trafik jeneratör olduğunu. Mesajlar tam olarak oradaysa, bu arama motorlarında görünürlüğü artırabilir
Pekka

2
@Pekka understand Anlıyorum. Sadece söyledim çünkü URL daha önce kesilmedi ve şimdi de öyle and-notice-undef. Bu sadece (birkaç) öneriydi. Sadece kendini de tekrar eder Notice: Undefined.
Funk Forty Niner

Yanıtlar:


1066

Uyarı: Tanımsız değişken

PHP Manual'ın geniş bilgeliğinden :

Başlatılmamış bir değişkenin varsayılan değerine güvenmek, aynı değişken adını kullanan bir dosyanın diğerine dahil edilmesi durumunda sorunludur. Aynı zamanda bir uzmanı güvenlik riski ile register_globals döndü. Başlatılmamış değişkenlerle çalışma durumunda E_NOTICE düzey hatası verilir, ancak başlatılmamış diziye öğe ekleme durumunda değil. isset () dil yapısı, bir değişkenin zaten başlatılıp başlatılmadığını tespit etmek için kullanılabilir. Ek ve daha ideal, değişken başlatılmazsa bir uyarı veya hata mesajı üretmediği için empty () çözümüdür .

Gönderen PHP belgelerine :

Değişken yoksa uyarı üretilmez. Bunun anlamı empty () aslında ! İsset ($ var) || $ var == yanlış .

Yalnızca kullanabileceği Bu araçlar empty()değişken ayarlanmış olup olmadığını belirlemek için, ve buna ek olarak karşısına şunlar değişkeni denetler 0, 0.0, "", "0", null, falseveya [].

Misal:

$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";
});

Yukarıdaki pasajı 3v4l.org çevrimiçi PHP editöründe test edin

PHP değişken bildirimi gerektirmemesine rağmen, komut dosyasında daha sonra kullanılacak bir değişkene değer vermeyi unutabilecek bazı güvenlik açıklarını veya hatalarını önlemek için bunu öneriyor. Belirtilmemiş değişkenler durumunda PHP'nin yaptığı, E_NOTICEvarsayılan olarak rapor edilmeyen çok düşük seviyeli bir hatadır , ancak Kılavuz geliştirme sırasında izin vermeyi önerir .

Sorunla başa çıkma yolları:

  1. Önerilen: Değişkenlerinizi bildirin, örneğin tanımsız bir değişkene bir dize eklemeye çalıştığınızda. Veya aşağıdaki gibi, kaynak göstermeden önce bildirilip bildirilmediğini kontrol etmek için isset()/ !empty()düğmesini kullanın :

    //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'] : '';

    Bu PHP 7.0 itibariyle çok daha temiz hale geldi, şimdi null birleştirme operatörünü kullanabilirsiniz :

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
  2. E_NOTICE için özel bir hata işleyici ayarlayın ve iletileri standart çıktıdan uzağa yönlendirin (belki bir günlük dosyasına):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
  3. E_NOTICE raporunu devre dışı bırak. Hariç tutmanın hızlı bir yolu E_NOTICE:

    error_reporting( error_reporting() & ~E_NOTICE )
  4. @ İşleci ile hatayı bastırın .

Not: 1. maddeyi uygulamanız önemle tavsiye edilir.

Uyarı: Tanımsız dizin / Tanımsız ofset

Bu bildirim, siz (veya PHP) bir dizinin tanımlanmamış dizinine erişmeye çalıştığınızda görüntülenir.

Sorunla başa çıkma yolları:

  1. Dizine erişmeden önce var olup olmadığını kontrol edin. Bunun için isset()veya kullanabilirsiniz 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. Dil yapısı list(), var olmayan bir dizi dizinine erişmeye çalıştığında bunu oluşturabilir:

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

İki dizi öğesine erişmek için iki değişken kullanılır, ancak yalnızca bir dizi öğesi, dizin vardır 0;

Uyarı: Tanımsız ofset: 1

$_POST/ $_GET/ $_SESSIONdeğişken

Yukarıdaki bildirimler $_POST, $_GETveya ile çalışırken sıklıkla görünür $_SESSION. İçin $_POSTve $_GETkullanmadan önce dizinin var olup olmadığını kontrol etmeniz yeterlidir. Çünkü $_SESSIONoturumu başlattığınızdan session_start()ve dizinin de var olduğundan emin olmalısınız .

Ayrıca 3 değişkenin de süper küresel olduğunu ve büyük harf olduğunu unutmayın .

İlişkili:


7
@ dieselpower44 Birkaç düşünce: "Kapatma operatörü" ( @) bazı performans sorunlarına sahiptir. Ayrıca, belirli bir kapsamdaki tüm hataları bastırdığı için, dikkatsiz kullanmak, görmenizi istediğiniz iletileri maskeleyebilir.
IMSoP

6
Sorunları gizlemek, sorunların üstesinden gelmenin yolu DEĞİLDİR. # 2 ... # 4 maddeleri genel olarak değil, yalnızca üretim sunucularında kullanılabilir.
Salman A

1
Özel bir hata işleyici de kullanıldığında mesaj satır içi (işleyicide değil) kapatılabilir mi? $var = @$_GET['nonexisting'];hala bildirime neden oluyor ..
Alph.Dev

18
Neden $value = isset($_POST['value']) ? $_POST['value'] : '';4. yerine 4. kullanmanız önerilir $value = @$_POST['value'];?
forsvunnet

@twistedpixel Bu 4 yöntem bağımsızdır, bu 4 adımlı bir kılavuz değildir. Bu nedenle, 4. yolu kullanmayı seçtiyseniz, bu, ilk 3 yolu uygulamadığınız anlamına gelir, bu nedenle henüz herhangi bir hatayı bastırmadınız.
Aycan Yaşıt

141

Bunları dene

S1: Bu bildirim $ varname komut dosyasının geçerli kapsamında tanımlanmadığı anlamına gelir.

S2: Herhangi bir şüpheli değişken kullanmadan önce isset (), empty () koşullarının kullanılması iyi sonuç verir.

// 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'];
}

Veya hızlı ve kirli bir çözüm olarak:

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

Oturumlar hakkında not:


Kullanılıyorsa E_NOTICEgelen php.iniyapılandırma dosyası, doerror_reporting = (E_ALL & ~E_NOTICE)
ahmd0


Yukarıdaki cevaptan, isset, dizi_anahtar_exists denedim ama bu işe yaramadı. Cevabınızı denedim, .empty () ve işe yarıyor. Çok teşekkür ederim!
ewef

63

Hata görüntüleme @operatörü

İstenmeyen ve gereksiz bildirimler için, tanımlanmamış değişken / dizin mesajlarını » gizlemek için özel @operatör kullanılabilir .

$var = @($_GET["optional_param"]);
  • Bu genellikle önerilmez. Yeni gelenler aşırı kullanım eğilimindedir.
  • Örneğin uygulama parametreleri veya döngüler gibi uygulama mantığının derinliklerindeki kodlar (yapmamanız gereken bildirilmemiş değişkenleri yok saymak) çok uygun değildir.
  • Ancak üst baskı isset?:veya ??süper-supresyon üzerinde bir tane var . Bildirimler hala kaydedilebilir. Ve @-hidden bildirimleri diriltebilir:set_error_handler("var_dump");
    • Ayrıca alışkanlık olarak kullanmamalı / tavsiye etmemelisiniz if (isset($_POST["shubmit"])) , ilk kodunuzda .
    • Yeni gelenler bu tür yazım hatalarını görmezler. Sadece bu durumlar için PHP Bildirimleri sizi mahrum eder. Ekleme @veya issetyalnızca işlevselliği doğruladıktan sonra .
    • Önce nedeni düzeltin. Bildirimler değil.

  • @$_GET/ $_POSTinput parametreleri için özellikle kabul edilebilir olmaları özellikle kabul edilebilir .

Ve bu, bu tür soruların çoğunu kapsadığından, en yaygın nedenleri genişletelim:

$_GET/ $_POST/ $_REQUESTtanımsız girdi

  • Tanımsız bir indeks / ofset ile karşılaştığınızda yaptığınız ilk şey yazım hatalarını kontrol etmektir:
    $count = $_GET["whatnow?"];

    • Bu beklenen bir anahtar adı mı ve her sayfa isteğinde mevcut mu?
    • Değişken adları ve dizi göstergeleri PHP'de büyük / küçük harfe duyarlıdır.
  • İkincisi, bildirimin belirgin bir nedeni var_dumpyoksa , akıcı içerikleri için tüm giriş dizilerini print_rdoğrulamak için veya kullanın :

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

    Her ikisi de komut dosyanızın doğru veya herhangi bir parametre ile çağrıldığını gösterir.

  • Alternatif olarak veya ek olarak tarayıcı cihazlarınızı ( F12) kullanın ve ağ sekmesini istek ve parametreler açısından inceleyin:

    tarayıcı geliştirici araçları / ağ sekmesi

    POST parametreleri ve GET girişi ayrı ayrı gösterilir.

  • İçin $_GETparametrelerin en gözetleme de yapabilirsiniz QUERY_STRINGin

    print_r($_SERVER);

    PHP, standart olmayan parametre adlarını süper küresellerle birleştirmek için bazı kurallara sahiptir . Apache de yeniden yazma işlemi yapabilir. Ayrıca, sağlanan ham $_COOKIESve diğer HTTP istek başlıklarına bu şekilde bakabilirsiniz .

  • Daha açık bir şekilde GET parametreleri için tarayıcı adres çubuğunuza bakın :

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

    name=valueSonra çiftleri ?soru işareti sorgu (GET) parametrelerdir. Böylece bu URL yalnızca $_GET["id"]ve $_GET["sort"].

  • Son olarak bir parametre bekliyorsanız ve hiçbirini almıyorsanız, bildirimlerinizi <form>ve<input> bildirimlerinizi kontrol edin .

    • Gerekli her girişin bir <input name=FOO>
    • id=Veya title=nitelik yetmiyor.
    • Bir method=POSTformun doldurulması gerekir $_POST.
    • Oysa a method=GET(ya da dışarıda bırakmak) $_GETdeğişkenler getirecektir .
    • Bir formun action=script.php?get=param$ _GET üzerinden ve kalan method=POSTalanları $ _POST ile birlikte sağlaması da mümkündür .
    • Modern PHP konfigürasyonları (≥ 5.6) ile GET ve POST parametrelerini birleştiren tekrar kullanılabilir (modaya uygun değil) $_REQUEST['vars'].
  • Mod_rewrite kullanıyorsanız, yok parametrelerini bulmak için hem hem işaretini hem access.logde etkinleştirmelisiniz RewriteLog.

$_FILES

  • Dosya yüklemeleri ve için de aynı sağlık kontrolleri geçerlidir $_FILES["formname"].
  • Ayrıca kontrol edin enctype=multipart/form-data
  • Yanı sıra method=POSTsizin de <form>bildiriminde.
  • Ayrıca bkz: PHP Tanımsız dizin hatası $ _FILES?

$_COOKIE

  • $_COOKIEDizi hemen sonra doldurulan asla setcookie()ama sadece herhangi takip HTTP isteği üzerine,.
  • Ek olarak geçerlilikleri zaman aşımına uğrar, alt alan adları veya tek tek yollar için kısıtlama olabilir ve kullanıcı ve tarayıcı bunları reddedebilir veya silebilir.

2
Performansın etkisinin ne olduğunu merak ediyorsanız, bu makale bunu iyi özetliyor, derickrethans.nl/… .
Gajus

@GajusKuizinas 2009'dan bu yana birkaç değişiklik yapıldı, özellikle php.net/ChangeLog-5.php#5.4.0 sonucu önemli ölçüde değiştirdi (bkz. "Zend Engine, performans" ve "(sessizlik) operatörü").
mario

Teşekkürler @ mario, ilginç. Şimdi, birisi ikisini karşılaştırmak için yeterince iyi olsaydı ... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs Bu teste göre, aynı gibi görünüyor (ölçeğin değiştiğine dikkat edin).
Gajus

47

Genellikle "kötü programlama" ve şimdi veya daha sonra hata olasılığı nedeniyle.

  1. Hatalıysa, önce değişkene uygun bir atama yapın: $ varname = 0;
  2. Gerçekten sadece bazen tanımlanıyorsa, test edin: if (isset($varname)) kullanmadan önce
  3. Eğer yanlış hecelediğiniz için, düzeltin
  4. Belki PHP ayarlarınızdaki uyarıları bile

5
Lütfen uyarıları kapatmayın. Daha katı dillerde, genellikle "bir hata olabilir, bu satırı iki kez kontrol etseniz iyi olur" - PHP kadar izin veren bir dilde, genellikle "bu kod saçmalık ve hatalarla muhtemelen delinmiş demektir; bir anlamda ama bu ASAP'ı düzeltsen iyi olur ".

5
İlk üç noktayı kabul etsem de # 4 yanlış. Bir sorunu gizlemek sorunu ortadan kaldırmaz ve hatta yolda daha fazla soruna neden olabilir.
Valentin Flachsel

1
@Freek kesinlikle doğru, ancak bazı senaryolarda (Satın alınan senaryo, sıfır teknik bilgi, yarına kadar çalışmasına ihtiyaç var ...) bu koli bandı çözümü - gerçekten kötü, her zaman vurgulanması gereken, ancak bir seçenek
Pekka

Koli bandı iyidir ... bazen. Tarihsel olarak uyarılar standart PHP ayarlarında kapatılmıştır, ancak defult ayarları daha katı hale gelmiştir. Çok kötü birçoğu müşterileri rahatsız etmemek için eski ayarlara geri döner.
Erik

41

Bu, henüz bir şey atamadığınız bir değişkeni test ettiğiniz, değerlendirdiğiniz veya yazdırdığınız anlamına gelir. Bu, bir yazım hatası yaptığınız veya değişkenin önce bir şeye başlatıldığını kontrol etmeniz gerektiği anlamına gelir. Mantık yollarınızı kontrol edin, bir yolda ayarlanmış olabilir, ancak başka bir yolda ayarlanmamış olabilir.


34

Yararlı olduğu için bildirimi devre dışı bırakmak istemedim, ancak çok fazla yazmayı önlemek istedim.

Benim çözümüm bu işlevdi:

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

Yani eğer $ name ve echo varsa başvurmak istersem, sadece şunu yazarım:

<?=ifexists('name')?>

Dizi elemanları için:

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

Sayfada $ _REQUEST ['name'] ifadesine başvurmak istersem:

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

2
İfexists () işleviniz PHP 5.3'te benim için çalışmıyor. Arayan değişkenleri, Superglobals olmadıkça veya $ GLOBALS ile uğraşmadıkça , işlevin yerel kapsamında kullanılamaz (bkz. Değişken kapsamı ), genel olarak null değerini döndürür. (İtalik $foo = "BABAR"; ifexists('foo');
php.net

şimdi "merhaba" dan alacaksın ... ne anlamı var? sadece değeri kontrolif( !empty($user) and !empty($location) ) echo "hello $user ..."
gcb

27

Giriş dizesini almanın en iyi yolu :

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

Bu tek astar neredeyse şuna eşittir:

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

Kesinlikle dize değeri istiyorsanız , tıpkı şöyle:

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

25

Çünkü '$ user_location' değişkeni tanımlanmıyor. İçinde '$ user_location' değişkenini bildirdiğiniz herhangi bir if döngüsü kullanıyorsanız, başka bir döngüye sahip olmanız ve bunu tanımlamanız gerekir. Örneğin:

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

Yukarıdaki kod, if döngüsü tatmin edilmediğinden ve else döngüsünde '$ user_location' tanımlanmadığı için hata oluşturur. Yine de PHP'den değişkeni yankılaması istendi. Bu nedenle, kodu değiştirmek için aşağıdakileri yapmanız gerekir:

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

25

"" Yanıtı neden birden bire ortaya çıkıyor? Bu senaryoyu yıllarca kullanıyordum ve hiç problem yaşamadım. "

Çoğu sitenin "Tüm hataları göster, ancak" bildirimler "ve" kullanımdan kaldırıldı "ifadelerinin" varsayılan "hata raporlaması altında çalışması çok yaygındır. Bu php.ini dosyasında ayarlanır ve sunucudaki tüm sitelere uygulanır. Bu, örneklerde kullanılan bu "bildirimlerin" bastırılacağı (gizleneceği), daha kritik olduğu düşünülen diğer hataların gösterileceği / kaydedileceği anlamına gelir.

Diğer kritik ayar, hataların gizlenebilmesidir (yani display_errors"kapalı" veya "syslog" olarak ayarlanabilir).

Bu durumda ne olacağı ya error_reportingbildirimleri gösterecek şekilde değiştirilmiş (örneklere göre) ve / veya ayarların display_errors(bastırılması / kaydedilmesinin aksine) ekranda değiştirilmiş olmasıdır .

Neden değiştiler?

Açık / en basit cevap, birinin php.ini'deki bu ayarlardan birini ayarlaması veya PHP'nin yükseltilmiş bir versiyonunun şimdi daha önce farklı bir php.ini kullanmasıdır. Bakılacak ilk yer burası.

Ancak, bu ayarları geçersiz kılmak da mümkündür

  • .htconf (vhosts ve alt yapılandırmalar dahil web sunucusu yapılandırması) *
  • .htaccess
  • php kodunun kendisinde

ve bunların herhangi biri de değiştirilebilirdi.

Ayrıca, web sunucusu yapılandırmasının .htaccess yönergelerini etkinleştirebileceği / devre dışı bırakabileceği ek bir karmaşıklık vardır, bu nedenle .htaccess'te aniden çalışmayı başlatan / durduran yönergeler varsa, bunu kontrol etmeniz gerekir.

(.htconf / .htaccess, apache olarak çalıştığınızı varsayar. Komut satırını çalıştırırsanız bu geçerli olmaz; IIS veya başka bir web sunucusu çalıştırıyorsanız, bu yapılandırmaları buna göre kontrol etmeniz gerekir)

özet

  • Php.ini içindeki check error_reportingve display_errorsphp yönergeleri değişmemiştir veya daha önce farklı bir php.ini kullanmıyorsanız.
  • Kontrol edin error_reportingvedisplay_errors.Htconf (veya vhosts vb.) İçindeki php yönergeleri değişmedi
  • Kontrol edin error_reportingvedisplay_errors.Htaccess içindeki php yönergeleri değişmedi
  • .Htaccess içinde direktifiniz varsa, .htconf dosyasında buna izin verilip verilmediğini kontrol edin
  • Son olarak kodunuzu kontrol edin; muhtemelen ilgisiz bir kütüphane; error_reportingve display_errorsphp yönergelerinin orada ayarlanıp ayarlanmadığını görmek için .

20

hızlı düzeltme, değişkeninizi kodunuzun üst kısmındaki null değerine atamaktır

$user_location = null;

16

Bu hatayı lanetledim, ancak kullanıcı girişinden kaçmanızı hatırlatmak yardımcı olabilir.

Örneğin, bunun akıllı olduğunu düşünüyorsanız, kısayol kodu:

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

...Tekrar düşün! Daha iyi bir çözüm:

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

( html()Karakterlerden kaçmak için özel bir işlev kullanıyorum , kilometreniz değişebilir)


15

PHP 7.0'da Null birleştirme operatörü kullanmak artık mümkün:

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

Eşittir:

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

PHP kılavuzu PHP 7.0


Bu ayrıca if ifadelerinde de işe yarar. if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
bir kodlayıcı

Kod aslında güzel bir gözden kaçan bir hata: ?? - sadece denetler isset(), geçerseniz is_array()- ki bu bir boolean, beklenmedik bir davranış olacaktır.
elpiel

14

Değişkenleri otomatik olarak bildiren tüm zamanların kendi yararlı işlevlerini exst () kullanıyorum .

Kodunuz -

$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;
}

14

Çok Basit Bir Dilde .
Hata, $user_locationdaha önce sizin tarafınızdan tanımlanmayan ve herhangi bir değeri olmayan bir değişken kullanmanızdır. Bu nedenle, lütfen kullanmadan önce bu değişkeni bildirmenizi öneririz , Örneğin:


$user_location = '';
Veya
$user_location = 'Los Angles';
Bu, karşılaşabileceğiniz çok yaygın bir hatadır.Bu yüzden endişelenmeyin, sadece değişkeni bildirin ve Kodlamanın Keyfini Çıkarın .


8

neden işleri basit tutmuyorsun?

<?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

?>

8

BU NEDEN OLUYOR?

Zaman içinde PHP daha fazla güvenlik odaklı bir dil haline geldi. Varsayılan olarak önceden kapatılmış olan ayarlar artık varsayılan olarak açıktır. Bunun mükemmel bir örneği E_STRICT, PHP 5.4.0'dan itibaren varsayılan olarak açılan .

Ayrıca, PHP belgelerine göre E_NOTICEphp.ini dosyasında varsayılan olarak devre dışıdır. PHP dokümanları hata ayıklama amacıyla açılmasını önerir . Ancak, Ubuntu deposundan ve BitNami'nin Windows yığınından PHP'yi indirdiğimde başka bir şey görüyorum.

; 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

error_reportingVarsayılan olarak "varsayılan" değere değil, varsayılan olarak üretim değerine ayarlanmış olduğuna dikkat edin . Bu biraz kafa karıştırıcı ve ben var, bu yüzden php.ini dışında belgelenmiş değildir değil diğer dağıtımlarında bu valide.

Ancak sorunuzu cevaplamak için, daha önce açılmadığında bu hata şimdi ortaya çıkıyor çünkü:

  1. PHP'yi yüklediniz ve yeni varsayılan ayarlar biraz zayıf bir şekilde belgelenmiş ancak hariç tutulmuyor E_NOTICE.

  2. E_NOTICEtanımlanmamış değişkenler ve tanımlanmamış dizinler gibi uyarılar aslında kodunuzu daha temiz ve güvenli hale getirmeye yardımcı olur. Yıllar önce, E_NOTICEetkin kalmamın değişkenlerimi bildirmemi zorladığını söyleyebilirim. C'yi öğrenmeyi çok daha kolay hale getirdi, değişkenlerin rahatsızlıktan çok daha büyük olduğunu bildirmiyordu.

BU KONUDA NE YAPABİLİRİM?

  1. E_NOTICE"Varsayılan değer" i kopyalayıp E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATEDeşittir oturum açtıktan sonra şu anda önerilmeyenle değiştirerek kapatın error_reporting =. CGI veya FPM kullanıyorsanız Apache'yi veya PHP'yi yeniden başlatın. "Right" php.ini dosyasını düzenlediğinizden emin olun. PHP'yi Apache, fpm veya PHP-FPM çalıştırıyorsanız php-fpm, PHP-CGI, vb. Çalıştırıyorsanız cgi vb. İle çalıştırıyorsanız doğru olanı Apache olacaktır. Bu önerilen yöntem değildir, ancak eski kodunuz düzenlemek son derece zor olabilir, o zaman en iyi bahsiniz olabilir.

  2. E_NOTICEDosya veya klasör seviyesini kapatın . Bazı eski kodlarınız varsa, ancak işleri "doğru" şekilde yapmak istiyorsanız, bu tercih edilebilir. Bunu yapmak için Apache2, Nginx veya seçtiğiniz sunucunuz ne olursa olsun danışmalısınız. Apache'de, php_valueiçinde kullanabilirsiniz <Directory>.

  3. Daha temiz olması için kodunuzu yeniden yazın. Bir üretim ortamına geçerken bunu yapmanız gerekiyorsa veya birisinin hatalarınızı görmesini istemiyorsanız, hataların görüntülenmesini devre dışı bıraktığınızdan ve yalnızca hatalarınızı günlüğe kaydettiğinizden emin olun ( php.ini ve sunucu ayarlarınıza bakın display_errorsve log_errors) .

3. seçeneği genişletmek için: Bu idealdir. Bu rotaya gidebilirsen, yapmalısın. Başlangıçta bu rotaya gitmiyorsanız, kodunuzu bir geliştirme ortamında test ederek bu rotayı sonunda taşımayı düşünün. Siz oradayken, kurtulun ~E_STRICTve ~E_DEPRECATEDgelecekte neyin yanlış gidebileceğini görün. Bilmediğiniz bir sürü hata göreceksiniz, ancak gelecekte PHP'yi yükseltmeniz gerektiğinde hoş olmayan bir sorun yaşamanızı engelleyecektir.

HATALAR NE DEMEKTİR?

Undefined variable: my_variable_name- Bu, bir değişken kullanımdan önce tanımlanmadığında ortaya çıkar. PHP betiği yürütüldüğünde, dahili olarak sadece bir null değeri varsayar. Ancak, bir değişkeni tanımlanmadan önce hangi senaryoda kontrol etmeniz gerekir? Sonuçta, bu "özensiz kod" için bir argüman. Bir geliştirici olarak, değişkenlerin kapsamlarında tanımlanabileceği kadar yüksek olarak tanımlandığı açık kaynaklı bir proje gördüğümde onu sevdiğimi söyleyebilirim. Gelecekte hangi değişkenlerin açılacağını söylemeyi kolaylaştırır ve kodu okumayı / öğrenmeyi kolaylaştırır.

function foo()
{
    $my_variable_name = '';

    //....

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

Undefined index: my_index- Bu, bir dizideki bir değere erişmeye çalıştığınızda oluşur ve varolmaz. Bu hatayı önlemek için bir koşullu denetim gerçekleştirin.

// 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;   

Başka bir seçenek, işlevinizin üst kısmında boş bir dizi bildirmektir. Bu her zaman mümkün değil.

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

//...

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

(ek ipucu)

  • Bu ve diğer sorunlarla karşılaştığımda, NetBeans IDE'yi (ücretsiz) kullandım ve bana bir dizi uyarı ve bildirim verdi. Bazıları çok yararlı ipuçları sunuyor. Bu bir gereklilik değil ve IDE'leri artık büyük projeler dışında kullanmıyorum. vimBu günlerde daha çok insanım :).

6

tanımlanmamış dizin, örneğin, kullanılamayan dizi dizini için istediğiniz bir dizideki anlamına gelir

<?php 

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

?>

undefined değişkeni, tamamen var olmayan bir değişkeni kullandığınız veya bu adla tanımlanmayan veya başlatılmadığı anlamına gelir.

<?php print_r($myvar); ?>

undefined ofset, dizide mevcut olmayan anahtarı istemiş olduğunuz anlamına gelir. Ve bunun çözümü kullanımdan önce kontrol etmektir

php> echo array_key_exists(1, $myarray);

4

Sorunun bu kısmı ile ilgili:

Neden aniden ortaya çıkıyorlar? Bu senaryoyu yıllarca kullanıyordum ve hiç problem yaşamadım.

Kesin cevaplar yok, ancak ayarların neden 'aniden' değişebileceğine dair olası bazı açıklamalar:

  1. PHP'yi, hata_ raporlama, görüntü_ hataları veya diğer ilgili ayarlar için başka varsayılanları olabilen daha yeni bir sürüme yükselttiniz.

  2. Çalışma zamanındaki ilgili ayarları ini_set()veyaerror_reporting() (kodda bunları arayın

  3. Web sunucusu yapılandırmasını değiştirdiniz (burada apache olduğu varsayılarak): .htaccess dosyalar ve vhost yapılandırmaları php ayarlarını da değiştirebilir.

  4. Genellikle bildirimler görüntülenmez / raporlanmaz ( PHP kılavuzuna bakın ), bu nedenle sunucuyu kurarken php.ini dosyasının bir nedenden dolayı yüklenememesi (dosya izinleri ??) ve varsayılan ayarlarda olmanız mümkündür. . Daha sonra, 'hata' çözüldü (yanlışlıkla) ve şimdi bildirimleri göstermek için error_reporting ayarlı doğru php.ini dosyasını yükleyebilir.


3

Sınıflarla çalışıyorsanız, aşağıdakileri kullanarak üye değişkenlere başvurduğunuzdan emin olmanız gerekir $this:

class Person
{
    protected $firstName;
    protected $lastName;

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

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}

3

Tanımlanmamış bir dizin bildiriminin atılmasının bir başka nedeni, bir veritabanı sorgusundan bir sütunun atlanmış olmasıdır.

yani:

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

Ardından, bir döngü içinde daha fazla sütun / satıra erişmeye çalışın.

yani:

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

veya bir whiledöngü içinde:

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

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

}

Dikkat edilmesi gereken başka bir şey, * NIX OS ve Mac OS X'te durumların büyük / küçük harfe duyarlı olmasıdır.

Stack ile ilgili aşağıdaki Soru ve Cevaplara başvurun:


3

Üçlü kullanmak basit, okunabilir ve temizdir:

Pre PHP 7
Ayarlanmışsa başka bir değişkenin değerine bir değişken atayın, aksi takdirde atayınnull(veyaihtiyacınız olan varsayılan değeri):

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

PHP 7+
Aynı Null Birleştirme Operatörü kullanmak dışında . Artık isset()yerleşik olarak çağrı yapmaya gerek yoktur ve kontrol edilen değişkenin değerini döndürdüğü varsayıldığı için değişkeni döndürmeye gerek yoktur:

$newVariable = $thePotentialData ?? null;

Her ikisi de Bildirimler'i OP sorusundan durduracak ve her ikisi de aşağıdakilerin tam eşdeğeridir:

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

 
Yeni bir değişken ayarlamanız gerekmiyorsa, üçlünün döndürülen değerini doğrudan kullanabilirsiniz. echo işlev argümanları :

Eko:

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

İşlev:

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

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

Yukarıdaki, oturumlar vb.Dahil olmak üzere dizilerle aynı şekilde çalışacaktır, kontrol edilen değişkenin örneğin:
$_SESSION['checkMe']
veya ihtiyaç duyduğunuz birçok düzeyle ör.
$clients['personal']['address']['postcode']


 

Bastırma:

PHP Bildirimlerini bastırmak @veya hata raporlama seviyenizi azaltmak mümkündür , ancak sorunu çözmez sadece hata günlüğünde rapor edilmesini durdurur. Bu, kodunuzun hala ayarlanmamış bir değişkeni kullanmaya çalıştığı anlamına gelir; bu, eksik değerin ne kadar önemli olduğuna bağlı olarak, bir şeyin amaçlandığı gibi çalışmadığı anlamına gelebilir veya gelmeyebilir.

Bu sorunu gerçekten kontrol etmeli ve uygun bir şekilde ele almalı, farklı bir mesaj sunmalı veya hatta kesin durumu tanımlamak için diğer her şey için boş bir değer döndürmelisiniz.

Bildirimin hata günlüğünde olmamasını önemsiyorsanız, bir seçenek olarak hata günlüğünü göz ardı edebilirsiniz.


1

Bir HTML formu gönderildikten sonra var olmayan bir değişkenin yaygın nedenlerinden biri, form öğesinin bir <form>etiket içinde bulunmamasıdır :

Örnek: Öğe, <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>

Örnek: Öğe şimdi <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>

0

Muhtemelen şu ana kadar eski PHP sürümünü kullanıyordunuz ve şimdi PHP'yi yükseltti, şu ana kadar yıllardan beri hatasız çalışıyordu. PHP4'e kadar değişken tanımlanmadan kullanılırsa hata olmadı, ancak PHP5'ten itibaren söz konusu kodlar için hatalar atıyor.


0

Dosyalarla uğraşırken, forma dahil edilmezse tanımlanmamış bir dizin bildirimini tetikleyecek uygun bir şifreleme ve bir POST yöntemi gereklidir.

Kılavuzda aşağıdaki temel sözdizimi belirtilmektedir:

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>";

?>

Referans:


0

Bu konuda bir soru sordum ve bu mesaja şu mesajla yönlendirildim:

Bu sorunun burada zaten bir cevabı var:

PHP kullanarak “Uyarı: Tanımsız değişken”, “Uyarı: Tanımsız dizin” ve “Uyarı: Tanımsız ofset”

Soru ve çözümümü burada paylaşıyorum:

Bu hata:

resim açıklamasını buraya girin

Sorun 154 hattıdır. 154. sıradaki var:

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

Sorun, eğer değişken $citydeğil, koşul değil anahtar için değer yazıyorum olduğunu düşünüyorum $key => $city. İlk olarak, uyarının sebebinin bu olup olmadığını teyit edebilir misiniz? İkincisi, sorun buysa, neden değere dayalı bir koşul yazamıyorum? Durumu yazmak için ihtiyacım olan anahtarla mı olmalı?

GÜNCELLEME 1: Sorun, yürütme $citiesCounterArray[$key]sırasında bazen dizide $keybulunmayan bir anahtara karşılık $citiesCounterArraygelmesidir, ancak her zaman durumumun verilerine dayanarak durum böyle değildir. Ne gerek $keydizide varsa, daha sonra kodu çalıştırmak, aksi takdirde, atlamak bir koşul ayarlamaktır .

GÜNCELLEME 2: Bunu kullanarak bu şekilde düzelttim array_key_exists():

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

0

Bu hatalar, ayarlanmamış bir değişken kullandığımızda oluşur.

Bunlarla başa çıkmanın en iyi yolu, geliştirme sırasında hata raporlaması yapmaktır.

Üzerinde hata bildirimi ayarlamak için:

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

Üretim sunucularında hata bildirimi kapalı olduğundan bu hataları almıyoruz.

Ancak geliştirme sunucusunda hata raporlamayı açık olarak ayarlayabiliriz.

Bu hatadan kurtulmak için aşağıdaki örneği görüyoruz:

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

NULLDeğerleri atamadan veya kullanmadan önce değişkenleri başlatabiliriz .

Yani, kodu şu şekilde değiştirebiliriz:

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

Bu, herhangi bir program mantığını bozmayacak ve değeri olmasa bile Uyarı üretmeyecektir $test.

Yani, temel olarak, hata raporlamasını geliştirme için AÇIK yapmak her zaman daha iyidir.

Ve tüm hataları düzeltin.

Ve üretimde, hata raporlaması kapalı olarak ayarlanmalıdır.


-1

Bu bildirimler, kullanılan değişkene sahip olmadığınız definedve my_indexanahtarın değişken içinde bulunmadığı içindir $my_array.

Bu bildirimler her seferinde tetiklendi, çünkü code doğru değilsiniz, ancak muhtemelen bildirimleri bildirmediniz.

Hataları çözün:

$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 
}

Bunu çıkarmanın başka bir yolu:

ini_set("error_reporting", false)

-2

PHP'de değişkeni tanımlamak için yumruk kullanmanız gerekir.
Değişkenin tanımlanmış olup olmadığını çok etkili bir şekilde kontrol edebiliriz !.

//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)){

}

Basit Açıklama

//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";
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.