web-gelistirme-sc.com

"Notice: Undefined değişken", "Notice: Undefined index" ve "Notice: Undefined offset" kullanarak PHP

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

Uyarı: Tanımsız değişken: my_variable_name, C:\wamp\www\mypath\index.php satırındaki 10

Uyarı: Tanımsız dizin: my_index C:\wamp\www\mypath\index.php 11. satırda

Satır 10 ve 11 şöyle 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 birden bire ortaya çıkıyorlar? Yıllarca bu senaryoyu kullandım ve hiç sorun yaşamadım.

Onları nasıl düzeltebilirim?

Bu bir Genel Referans sorusu kişilerin tekrar tekrar açıklamak yerine, kopya olarak bağlantı kurması için. Bunun gerekli olduğunu düşünüyorum çünkü bu konudaki gerçek dünyadaki çoğu cevap çok spesifik.

İlgili Meta tartışması:

1069
Pekka 웃

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

PHP Manual 'in engin bilgeliğinden:

Başlatılmamış bir değişkenin varsayılan değerine güvenmek, bir dosyayı aynı değişken adını kullanan başka bir dosyaya dahil etmek durumunda sorunludur. Aynı zamanda, register_globals açıkken, güvenlik riski 'nin de bulunduğu büyüktür. E_NOTICE seviye hatası, başlatılmamış değişkenlerle çalışma durumunda verilir, ancak başlatılmamış diziye eleman eklenmesi durumunda. isset () dil yapısı, bir değişkenin zaten başlatılmış olup olmadığını tespit etmek için kullanılabilir. Ek olarak ve daha da ideal olanı, değişken başlatılmamışsa bir uyarı veya hata mesajı üretmediğinden empty () çözümünün çözümüdür.

PHP belgeden 'den:

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

Bu, değişkenin ayarlanıp ayarlanmadığını belirlemek için yalnızca empty() işlevini kullanabileceğiniz ve ek olarak değişkeni aşağıdaki 0,"",null ile denetleyeceği anlamına gelir.

Örnek:

$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 kod parçasını 3v4l.org çevrimiçi PHP düzenleyici içinde test edin.

PHP değişken bildirimi gerektirmese de, daha sonra komut dosyasında kullanılacak bir değişkene değer vermeyi unutacağı bazı güvenlik açıklarını veya hatalarını önlemek için bunu tavsiye eder. Bildirilmemiş değişkenler durumunda PHP'in yaptığı şey, çok düşük düzeyde bir hata, E_NOTICE, biri varsayılan olarak rapor edilmemiş, ancak El Kitabı izin vermeyi önerir geliştirmedir.

Bu konuyla başa çıkma yolları:

  1. Önerilen: Değişkenlerinizi, örneğin tanımsız bir değişkene bir dize eklemeye çalıştığınızda, bildirin. Veya, başvuruda bulunmadan önce bildirilip bildirilmediklerini kontrol etmek için isset() / !empty() 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 daha temiz bir hale geldi, şimdi boş birleştirme işleci kullanabilirsiniz:

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. E_NOTICE için bir özel hata işleyicisi ayarlayın ve mesajları 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’ın raporlamasını devre dışı bırakın. Yalnızca E_NOTICE öğesini dışlamanın hızlı bir yolu:

    error_reporting( error_reporting() & ~E_NOTICE )
    
  4. Hatayı @ operator ile bastırın.

Not: Sadece 1. maddeyi uygulamanız şiddetle önerilir.

Uyarı: undefined index/undefined offset

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

Bu konuyla başa çıkma yolları:

  1. Dizine erişmeden önce var olup olmadığını kontrol edin. Bunun için isset() veya array_key_exists() kullanabilirsiniz:

    //isset()
    $value = isset($array['my_index']) ? $array['my_index'] : '';
    //array_key_exists()
    $value = array_key_exists('my_index', $array) ? $array['my_index'] : '';
    
  2. list() dil yapısı, 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 vardır, index 0.

Uyarı: tanımsız ofset: 1

$_POST/$_GET/$_SESSION değişkeni

Yukarıdaki uyarılar, $_POST, $_GET veya $_SESSION ile çalışırken sıklıkla görünür. $_POST ve $_GET için, dizini kullanmadan önce var olup olmadığını kontrol etmeniz yeterlidir. $_SESSION için oturumu session_start() ile başlattığınızdan ve dizinin de bulunduğ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.

İlgili:

981
Alin Purcaru

Bunları dene

S1: Bu uyarı, betiğin şu anki alanında $ varname tanımlanmadığını gösterir.

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

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

Oturumlarla ilgili not:

123
Ish

Hata gösterimi @ operator

İstenmeyen ve yedekli bildirimler için, biri ayrılmış @ operatörü - " hide " tanımsız değişken/dizin mesajlarını kullanabilir.

$var = @($_GET["optional_param"]);
  • Bu genellikle tavsiye edilmez. Yeni gelenler, aşırı kullanma eğilimindedir.
  • Uygulama mantığının derinliklerindeki kod için çok uygun değildir (bilmemeniz gereken bildirilmemiş değişkenleri yok sayarak). işlev parametreleri için veya döngü olarak.
  • Ancak isset?: veya ?? super-supression üzerinde bir tane var. Bildirimler hala günlüğe kaydedilebilir. Ve biri @- gizli bildirimleri şu şekilde diriltebilir: set_error_handler("var_dump");
    • Buna ek olarak, ilk kodunuzda if (isset($_POST["shubmit"])) komutunu kullanmamalı/tavsiye etmemelisiniz.
    • Yeni gelenler böyle yazım hataları görmezler. Sadece bu durumlar için sizi PHP Bildirimlerinden mahrum eder. Yalnızca @ veya issetekleyin after işlevselliğin doğrulanması.
    • Önce sebebi düzeltin. Bildirimler değil.

  • @ özellikle $_GET/$_POST giriş parametreleri için kabul edilebilir, özellikle isteğe bağlıysa.

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

$_GET/$_POST/$_REQUEST tanımsız girdi

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

    • Bu beklenen bir anahtar ad mı ve her sayfa isteğinde mi mevcut?
    • Değişken isimleri and dizi, PHP’de büyük/küçük harf duyarlıdır.
  • İkincisi, bildirimin belirgin bir nedeni yoksa, doğrulamak için var_dump veya print_r all giriş dizilerini doğrulayın. curent içeriği:

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

    Her ikisi de, betiğinizin doğru veya herhangi bir parametre ile çağrılıp çağrılmadığını ortaya çıkarır.

  • Alternatif olarak veya ayrıca browser devtools (F12) ve ağ sekmesini istekler ve parametreler için inceleyin:

    browser developer tools / network tab

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

  • $_GET parametreleri için QUERY_STRING

    print_r($_SERVER);
    

    PHP'nin süper kurallara birleştirme standart olmayan parametre adlarına bazı kuralları vardır. Apache de yeniden yazma yapabilir. Ayrıca verilen ham $_COOKIES ve diğer HTTP istek başlıklarına da bu şekilde bakabilirsiniz.

  • Açıkçası, tarayıcınızın adres çubuğuna GET parametreleri bakın:

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

    name=value soru işaretinden sonra ? çiftleri, sorgu (GET) parametrelerinizdir. Bu nedenle, bu URL yalnızca $_GET["id"] ve $_GET["sort"] öğelerini verebilir.

  • Sonunda bir parametre bekliyor ancak hiçbiri almıyorsanız <form> VE <input> bildirimlerinizi kontrol edin.

    • Gerekli her girişin bir <input name=FOO> olduğundan emin olun
    • id= veya title= niteliği yeterli değil.
    • Bir method=POST formu $_POST öğesini doldurmalıdır.
    • Oysa, bir method=GET (veya onu dışarıda bırakarak) $_GET değişkenlerini sağlar.
    • Bir formun $ _GET aracılığıyla action=script.php?get=param ve bunun yanında $ _POST içinde kalan method=POST alanlarını sağlaması da mümkündür.
    • Modern PHP konfigürasyonları (6 5.6) ile, ygulanabilir (modaya uygun değil), $_REQUEST['vars'] tekrar kullanıldı, ki GET ve POST params.
  • Mod_rewrite kullanıyorsanız, o zaman hem access.log 'ı kontrol etmeli hem de eksik parametreleri bulmak için RewriteLogNAME _ ' yi etkinleştirmelisiniz.

$_FILES

  • Aynı sağlık kontrolleri dosya yüklemeleri ve $_FILES["formname"] için de geçerlidir.
  • Ayrıca enctype=multipart/form-data dosyasını kontrol edin.
  • Ayrıca method=POST bildirimindeki <form>.
  • Ayrıca bakınız: PHP Tanımsız dizin hatası $ _FILES?

$_COOKIE

  • $_COOKIE dizisi, setcookie() öğesinden hemen sonra doldurulmaz, ancak yalnızca izleyen HTTP isteğinde.
  • Ek olarak, geçerliliği zaman aşımına uğradıysa, alt alanlar veya tek tek yollar için kısıtlamalar olabilir ve kullanıcı ve tarayıcı bunları reddedebilir veya silebilir.
58
mario

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

  1. Eğer bir hata ise, önce değişkene uygun bir atama yapın: $ varname = 0;
  2. Gerçekten sadece bazen tanımlanmışsa, sınayın: if (isset($varname)), kullanmadan önce
  3. Yanlış yazıldığından dolayı, düzeltmek için
  4. Belki de içindeki uyarıları bile kapatırım PHP-settings
41
Erik

Bu, henüz bir şey tahsis etmediğiniz bir değişkeni test ettiğiniz, değerlendirdiğiniz veya yazdırdığınız anlamına gelir. Bu bir yazım hatası olduğunu ya da değişkenin ilk olarak başlatıldığını kontrol etmeniz gerektiğini gösterir. Mantık yollarınızı kontrol edin; bir yoldan başka bir yere ayarlanmamış olabilir.

38
DGM

Bildirimi devre dışı bırakmak istemedim çünkü faydalı, ancak çok fazla yazı yazmaktan kaçınmak istiyordu.

Benim çözümüm bu fonksiyondu:

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

Bu yüzden $ ismine başvurmak ve varsa eko yapmak istersem, şunu yazarım:

<?=ifexists('name')?>

Dizi elemanları için:

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

Sayfada $ _REQUEST ['name'] bölümüne başvurmak istersem:

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

string 'ı elde etmenin 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 string value istiyorsanız, aynen şöyle:

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

"" yanıtına neden birden bire gözüküyorlar? Bu senaryoyu yıllarca kullandım ve hiç sorun yaşamadım. "

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

Diğer kritik ayar ise hataların gizlenebilmesidir (örneğin, display_errors "off" veya "syslog" olarak ayarlanmıştır).

Bu durumda olan şey, ya error_reporting öğesinin de bildirimleri gösterecek şekilde değiştirildiği (/ örneklere göre) ve/veya ayarların ekrandaki display_errors olarak değiştirildiği (bunları bastırmak/günlüğe kaydetmek yerine) olmasıdır.

Neden değiştiler?

En açık/basit cevap, birinin bu ayarlardan birini php.ini dosyasında ya da PHP sürümünün yükseltilmiş bir sürümünün şimdi eskisinden farklı bir php.ini kullanıyor olmasıdır. Bakılacak ilk yer orası.

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

  • .htconf (vhosts ve alt yapılandırmaları içeren web sunucusu yapılandırması) *
  • .htaccess
  • php kodunun içinde

ve bunlardan herhangi biri de değişmiş olabilir.

Ayrıca web sunucusu konfigürasyonunun .htaccess yönergelerini etkinleştirmesi/devre dışı bırakması gibi ek bir komplikasyon da 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ıyorsanız, bu geçerli olmaz; IIS veya başka bir web sunucusu kullanıyorsanız, o zaman bu yapılandırmaları kontrol etmeniz gerekir)

Özet

  • Php.ini içindeki error_reporting ve display_errors php yönergelerinin değişmediğini veya öncekinden farklı bir php.ini kullanmadığınızı kontrol edin.
  • .Htconf (veya vhosts vb.) İçindeki error_reporting ve display_errors php yönergelerinin değişmediğini kontrol edin.
  • .Htaccess içindeki error_reporting ve display_errors php yönergelerinin değişmediğini kontrol edin
  • .Htaccess'te yönergeniz varsa, bunların hala .htconf dosyasında izin verilip verilmediğini kontrol edin.
  • Sonunda kodunuzu kontrol edin; muhtemelen ilgisiz bir kütüphane; error_reporting ve display_errors php yönergelerinin orada ayarlanmış olup olmadığını görmek için.
24
Robbie

Çünkü '$ user_location' değişkeni tanımlanmıyor. İçinde '$ user_location' değişkenini bildirdiğiniz if if döngüsünü kullanıyorsanız, başka bir döngüye de sahip olmanız ve aynısını 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ü karşılanmadığında ve başka bir döngüde '$ user_location' tanımlanmadığından hata oluşturacaktır. Yine de PHP'den değişkeni eklemesi 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;
24
Roger

hızlı düzeltme, değişkeninizi kodunuzun üstünde null değerine atamaktır.

$user_location = null;
19

Bu hatayı lanetlemek için kullanılırdım, ancak kullanıcı girişinden kaçmanızı hatırlatmakta yardımcı olabilirim.

Örneğin, bunun akıllıca olduğunu düşünüyorsanız, kısa yol 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']) : ''?>

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

15
rybo111

Tüm zamanları kendi yararlı fonksiyonunu kullanırım exst () değişkenleri otomatik olarak bildirir.

Kodunuz - olacak

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

PHP 7.0'da Null birleştirme operatörünü 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

13
Lachezar Lechev

NEDEN IS BU HAPPENING?

Zamanla, PHP daha güvenlik odaklı bir dil haline geldi. Varsayılan olarak kapatılmış olan ayarlar şimdi varsayılan olarak açıktır. Bunun mükemmel bir örneği, varsayılan olarak PHP 5.4.0 olarak açık olan E_STRICT şeklindedir.

Ayrıca, PHP belgelerine göre, php.ini dosyasında E_NOTICE varsayılan olarak devre dışı bırakılmıştır. PHP docs hata ayıklama amaçları için açma ) önerir. Ancak, PHP Ubuntu deposundan indirdiğimde ve BitNami'nin Windows yığınından 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_reporting öğesinin aslında varsayılan olarak "varsayılan" değerine değil, varsayılan olarak üretim değerine ayarlandığına dikkat edin. Bu biraz kafa karıştırıcı ve php.ini dışında belgelenmemiş, bu yüzdennotbunu diğer dağıtımlarda doğruladım.

Bununla birlikte, sorunuzu yanıtlamak için bu hata daha önce açılmadığında ortaya çıkıyor, çünkü:

  1. PHP ürününü yüklediniz ve yeni varsayılan ayarlar biraz kötü belgelendi, ancak E_NOTICE öğesini dışlamayın.

  2. E_NOTICE tanımsız değişkenler ve tanımsız dizinler gibi uyarılar aslında kodunuzu daha temiz ve daha güvenli hale getirmeye yardımcı olur. Yıllar önce, E_NOTICE işlevini açık tutmamın değişkenlerimi beyan etmemi sağladığını söyleyebilirim. C'nin öğrenilmesini çok daha kolay hale getirdi, değişkenlerin sıkıntıdan çok daha büyük olduğunu ilan etmedi.

BU KONUDA NE YAPABİLİRİM?

  1. "Varsayılan değer" E_NOTICE 'i kopyalayıp E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED içindeki eşittir işaretinden sonra şu anda uncommented olanı değiştirerek error_reporting = öğesini kapatın. CGI veya FPM kullanıyorsanız Apache'yi veya PHP uygulamasını yeniden başlatın. "Right" php.ini dosyasını düzenlediğinizden emin olun. Apache, PHP ile Apache, fpm veya php-fpm çalıştırıyorsanız, PHP-FPM kullanıyorsanız cgi, PHP-CGI çalıştırıyorsanız cgi, vs. ise doğru olan Apache olacaktır. Düzenlemesi son derece zor olacak olan kod, o zaman en iyi seçeneğiniz olabilir.

  2. Dosya veya klasör düzeyinde E_NOTICE işlevini 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 tercih ettiğiniz sunucunun ne olduğuna bakmalısınız. Apache'de, php_value içinde <Directory> öğesini kullanırsınız.

  3. Kodunuzu daha temiz olması için yeniden yazın. Bunu bir üretim ortamına taşırken yapmanız veya birisinin hatalarınızı görmesini istemiyorsanız, herhangi bir hata gösterimini devre dışı bıraktığınızdan emin olun ve yalnızca logging hatalarınızı görün (bkz. display_errors ve log_errors php.ini ve sunucu ayarlarınız).

Seçenek 3'te genişletmek için: Bu idealdir. Bu rotaya gidebilirsen, yapmalısın. Bu rotaya başlangıçta gitmiyorsanız, kodunuzu bir geliştirme ortamında sınayarak bu rotayı sonunda taşımayı düşünün. Bu işteyken, gelecekte neyin yanlış gidebileceğini görmek için ~E_STRICT ve ~E_DEPRECATED dosyalarından kurtulun. Çok fazla bilinmeyen hata göreceksiniz, ancak gelecekte PHP yükseltmeniz gerektiğinde rahatsız edici bir sorun yaşamanızı önleyecektir.

HATALAR NELERDİR?

Undefined variable: my_variable_name - Bir değişken kullanımdan önce tanımlanmadığında oluşur. PHP betiği yürütüldüğünde, dahili olarak bir boş değer varsayar. Ancak, hangi senaryoda bir değişkeni tanımlanmadan önce kontrol etmeniz gerekir? Sonuçta, bu "özensiz kod" için bir argümandır. Bir geliştirici olarak, değişkenlerin tanımlandıkları kadar kapsamlarında yüksek olarak tanımlandığı bir açık kaynak projesi gördüğümde onu sevdiğimi söyleyebilirim. Gelecekte hangi değişkenlerin ortaya çıkacağı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 - Dizideki bir değere erişmeye çalıştığınızda oluşur ve bu yoktur. Bu hatayı önlemek için koşullu kontrol yapın.

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

Diğer bir seçenek ise, fonksiyonunuzun üstünde 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 konularla karşılaştığımda, NetBeans IDE (free) kullandım ve bana bir dizi uyarı ve uyarı verdi. Bazıları çok yararlı ipuçları veriyorlar. Artık büyük projeler dışında IDE kullanmıyorum. Bugünlerde daha fazla vim kişisiyim :).
7
smcjones

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

?>
7
gts

undefined index, kullanılamayan dizi dizini için istediğiniz bir dizide, örneğin

<?php 

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

?>

tanımlanmamış değişken, tamamen mevcut değişkeni kullanmadığınız veya bu isim tarafından tanımlanmamış veya başlatılmayan anlamına gelir.

<?php print_r($myvar); ?>

undefined ofset, var olmayan anahtar için istediğiniz dizide anlamına gelir. Ve bunun için çözüm kullanımdan önce kontrol etmektir

php> echo array_key_exists(1, $myarray);
5
Sinte

Sorunun bu kısmı ile ilgili olarak:

Neden birden bire ortaya çıkıyorlar? Yıllarca bu senaryoyu kullandım ve hiç sorun yaşamadım.

Kesin bir cevap yok, ancak ayarların neden aniden değişebildiğine dair bazı olası açıklamalar:

  1. PHP öğesini, error_reporting, display_errors veya diğer ilgili ayarlar için başka varsayılanlara sahip olabilecek daha yeni bir sürüme yükselttiniz.

  2. ini_set() veya error_reporting() işlevlerini kullanarak çalışma zamanında ilgili ayarları yapan bazı kodları (muhtemelen bağımlılıkta) kaldırdınız veya getirdiniz (bunları kodda arayın)

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

  4. Genellikle bildirimler görüntülenmez/bildirilmez (bkz. PHP manual ), bu nedenle sunucuyu kurarken php.ini dosyasının bir nedenden ötürü yüklenememesi mümkündür (dosya izinleri) ??) ve varsayılan ayarlarda idi. Daha sonra, 'hata' (kazara) çözüldü ve şimdi doğru php.ini dosyasını hata bildirimleriyle ayarlanan error_reporting ile yükleyebilir.

3
Wouter de Winter

Sınıflarla çalışıyorsanız, üye değişkenlerine $this kullanarak başvuru yaptığınızdan emin olmanız gerekir:

class Person
{
    protected $firstName;
    protected $lastName;

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

        // Incorrect
        $lastName = $last;

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

Tanımlanamayan bir indeks bildiriminin atılmasının bir başka nedeni, bir sütunun bir veritabanı sorgusundan çıkarılmış olmasıdır.

Yani .:

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

Sonra bir döngü içinde daha fazla sütun/satır erişmeye çalışıyor.

Yani .:

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

veya while döngüsünde:

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 bir başka husus da, * NIX OS ve Mac OS X'te, durumların büyük/küçük harf duyarlı olmasıdır.

Stack'taki aşağıdaki Q & A'ya danışın:

2
Funk Forty Niner

Bir ternary kullanmak basit, okunabilir ve temiz:

Pre PHP 7
Ayarlandıysa başka bir değişkenin değerine bir değişken atayın, aksi takdirde nullveya ihtiyacınız olan varsayılan değerini atayın):

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

_ (PHP 7+
Null Coalescing Operator'ü kullanmak haricinde aynı. Bu yerleşik olarak isset() işlevini çağırmaya artık gerek yok ve kontrol edilen değişkenin değerini döndürdüğü varsayıldığı gibi geri döndürmek için değişkeni sağlamaya gerek yok:

$newVariable = $thePotentialData ?? null;

Her ikisi deOP sorusundaki Bildirimleri durduracak ve ikisi detam eşdeğeridir:

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


Yeni bir değişken ayarlamanız gerekmiyorsa, o zaman echo, function argümanları, vb. Gibi, üçlünün döndürdüğü değeri doğrudan kullanabilirsiniz:

Echo:

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ıdakiler, örn. İle kontrol edilen değişkenin yerine, oturumlar vb. Dahil olmak üzere dizilerle aynı şekilde çalışacaktır.
$_SESSION['checkMe']
veya ihtiyaç duyduğunuz birçok seviye, örneğin:
$clients['personal']['address']['postcode']


Bastırma:

PHP @ ile bildirimler bastırmak ya da hata raporlama seviyenizi azaltmak mümkündür, ancak sorunu çözmez, sadece hata günlüğünde raporlanmayı durdurur. kod hala ayarlanmamış bir değişkeni kullanmaya çalıştı, ki bu, eksik değerin ne kadar önemli olduğuna bağlı olarak bir şeyin olması gerektiği gibi çalışmadığı anlamına gelmeyebilir.

Bu konuyu gerçekten kontrol etmeli ve uygun bir şekilde ele almalısınız, farklı bir mesaj iletiyor ya da kesin durumu tanımlamak için her şey için boş bir değer döndürüyorsunuz.

Yalnızca Hata günlüğünde olmayan Bildirimi önemsiyorsanız, seçenek olarak hata günlüğünü yok sayabilirsiniz.

1
James

Bununla ilgili bir soru sordum ve bu mesaja şu mesajla yönlendirildim:

Bu sorunun zaten burada bir cevabı var:

PHP ile “Notice: Undefined değişken”, “Notice: Undefined index” ile “Notde: Undefined”;

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

Bu hatadır:

 enter image description here

154 numaralı hat sorun. 154 numaralı hattımda sahip olduğum şey bu:

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

Sanırım sorun, eğer kod değil $city değişkenindeki $key => $city değişkeni için şartlar varsa yazıyorum. Öncelikle, uyarının nedeni olup olmadığını onaylayabilir misiniz? İkincisi, eğer sorun buysa, neden değeri temel alarak bir koşul yazamıyorum? Koşulu yazmak için ihtiyacım olan anahtarın yanında olmak zorunda mı?

GÜNCELLEME 1: Sorun, $citiesCounterArray[$key] yürütülürken bazen $key, $citiesCounterArray dizisinde bulunmayan bir anahtara karşılık gelir, ancak bu benim döngümün verilerine dayanarak her zaman böyle değildir. İhtiyacım olan bir koşul koymak, böylece dizide $key varsa, sonra kodu çalıştırın, aksi takdirde atlayın.

GÜNCELLEME 2: Bu nasıl array_key_exists() kullanarak düzelttim:

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

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

Örnek: <form>içinde yer almayan öğe

<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: Artık <form>içinde yer alan öğe

<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
John Conde

Dosyalarla uğraşırken, formlara dahil edilmemişse tanımsız bir indeks bildirimini tetikleyecek uygun bir ense ve bir POST yöntemi gereklidir.

El kitabı aşağıdaki temel sözdizimini gösterir:

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 hatalar, ayarlanmamış bir değişken kullandığımızda meydana gelir.

Bunlarla başa çıkmanın en iyi yolu, geliştirme sırasında bildirilen hata bildirimidir.

Hata raporlamayı şu şekilde 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ı alamıyoruz.

Ancak geliştirme sunucusunda hata raporlamayı 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;

Değerlerini atamadan veya kullanmadan önce değişkenleri NULL olarak başlatabiliriz.

Böylece kodu şu şekilde değiştirebiliriz:

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

Bu hiçbir program mantığını bozmaz ve $test değeri olmasa bile Uyarı üretmez.

Dolayısıyla, temel olarak, geliştirme için hata bildirmeyi AÇIK hale getirmek her zaman daha iyidir.

Ve tüm hataları düzelt.

Ve üretimde hata raporlamanın kapalı olması gerekir.

0
Pupil

Muhtemelen eski PHP versiyonunu kullanıyordunuz ve şimdi yükselttikten sonra PHP yıllarca bugüne kadar hatasız çalışmasının nedeni bu. PHP4'e kadar eğer değişken tanımlamadan kullanıyorsanız hata yoktu ancak PHP5'ten itibaren söz konusu kodlar için hatalar atıyor.

0
phvish