Bir PHP işlevinde global bir değişkene erişin


84

Çoğu programlama dili kapsam kuralına göre, içlerindeki fonksiyonların dışında tanımlanan değişkenlere erişebilirim, ancak bu kod neden çalışmıyor?

<?php
    $data = 'My data';

    function menugen() {
        echo "[" . $data . "]";
    }

    menugen();
?>

Çıktı [].


3
Küresel olarak muamele bağımsız değişken olarak işleve geçmek etmeyin
Mark Baker

2
Kılavuz bu tür şeyleri nerede söylüyor?
deceze



afaik, $ GLOBALS ['varname'] kullanarak erişebiliriz, burada "varname" indeksi işlevin dışındaki $ değişkenadıdır. Aslına bakarsanız, tüm global değişkenleri görüntülemek için print_r ($ GLOBALS) kullanabiliriz.
Ahmad

Yanıtlar:


165

Çalışmıyor çünkü hangi global değişkenlere erişeceğinizi belirtmeniz gerekiyor:

$data = 'My data';

function menugen() {
    global $data; // <-- Add this line

    echo "[" . $data . "]";
}

menugen();

Aksi takdirde olarak erişebilirsiniz $GLOBALS['data']. Değişken kapsamına bakın .

Biraz konu dışı olsa bile, globalleri kullanmaktan kaçınmanızı ve parametre olarak geçmeyi tercih etmenizi öneririm.


Teşekkürler, Haklısın ama bu satırı ikinci kılavuz örneğinde kullanmadılar: php.net/manual/en/language.variables.scope.php
Amin Gholibeigian

6
Aslında bu ikinci örnek okuyuculara ne yapmamaları gerektiğini göstermek için oradaydı :This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope.
Matteo Tassinari

2
Dang! Bu cevabı yükseltmek için oturum açmak zorunda kaldım çünkü php değişkenlerinin kapsamını ürkütücü bir şekilde unuttum.
Milche Patern

20

Aşağıdakilerden birini yapabilirsiniz:

<?php
    $data = 'My data';

    function menugen() {
        global $data;
        echo "[" . $data . "]";
    }

    menugen();

Veya

<?php
    $data = 'My data';

    function menugen() {
        echo "[" . $GLOBALS['data'] . "]";
    }

    menugen();

Bununla birlikte, küresellerin aşırı kullanımı bazı kötü kodlara yol açabilir. İhtiyacınız olanı vermek genellikle daha iyidir. Örneğin, global bir veritabanı nesnesine referans vermek yerine, veritabanına bir tutamaç vermeli ve buna göre hareket etmelisiniz. Buna bağımlılık enjeksiyonu denir . Otomatikleştirilmiş testi uyguladığınızda (ki yapmalısınız) hayatınızı çok daha kolaylaştırır.


13

Bu bir kapsam meselesi. Kısacası, küresel değişkenlerden kaçınılmalıdır, bu nedenle :

Ya parametre olarak iletmeniz gerekir:

$data = 'My data';

function menugen($data)
{
    echo $data;
}

Veya bir sınıfta bulun ve ona erişin

class MyClass
{
    private $data = "";

    function menugen()
    {
        echo this->data;
    }

}

@ MatteoTassinari cevabına da bakın, çünkü ona erişmek için global olarak işaretleyebilirsiniz, ancak genel değişkenler genellikle gerekli değildir, bu nedenle kodunuzu yeniden düşünmeniz akıllıca olacaktır.


ve başka bir yol da global anahtar sözcüğünü kullanmaktır (verilmiş, bu en iyi yol değildir).
Jocelyn

1
"Gerekir" soruyu yanıtlamaz ve bu her durum için en iyi yaklaşım olmayabilir. Basit betikler için, etrafındaki parametreleri değiştirmek ve sınıf eklemek hantaldır. JavaScript gibi, PHP'de her şeyin nesne yönelimli olması ve wazoo'da ad alanlı olması gerekmez.
Beejor

@Beejor OP'nin adında bir işlevi menugen()olduğu için, sadece bir menü oluşturmaktan daha fazlası olacağı anlamına gelir. Örneğin, bu menüyü farklı bir kaynaktan daha fazla öğe eklemek için genişletmeye ne dersiniz, menüde o anda seçili olan sayfayı seçmeye ne dersiniz? Her yerde rastgele global değişkenlere ve mantığa sahip olmak, OOP tasarımı için çığlık atıyor. PHP / JS'nin yapılandırılması gerekmediği gerçeği, birçok dağınık hantal kod bulmanızın en büyük nedenlerinden biridir. Çok iyi yapılabilir, ancak insanların ileriye dönük sürdürülebilirlik hakkında hiçbir düşüncesine sahip olmamalarını sağlar.
webnoob

ps Aşağı oylama yanıtı da biraz kapalı. Cevap, OP'nin sorununa bir çözüm sağlıyor, sırf beğenmediğiniz için yanlış yapmıyor.
webnoob

1
@Beejor - Bu argümandaki sorun, insanların küresel bir değişkene ihtiyaç duyduklarını düşünmeleridir çünkü daha iyisini bilmiyorlar ve söylenmedikçe daha iyisini bilmiyorlar.
webnoob

11

Bunu yapmanın başka bir yolu:

<?php

$data = 'My data';

$menugen = function() use ($data) {

    echo "[".$data."]";
};

$menugen();

GÜNCELLEME 2020-01-13: Peter Mortensen tarafından talep edildi

PHP 5.3.0'dan itibaren, kapatmalar oluşturabilen anonim işlevler desteğine sahibiz. Bir kapanış, kapsamının dışında oluşturulan değişkene erişebilir.

Örnekte, tümcede $databildirildiği için kapanış erişebilir use.


Bu, başka bir fonksiyonun içinde değişken olarak tanımlanan bir fonksiyona sahip olduğum durumumda çalışan tek çözümdü. Global orada çalışmadı.
Kar.ma

Bir açıklama sırayla olacaktır. Örneğin, bu "kullanım" şeyi ne işe yarar? Bu "kullanım" şeyi hangi PHP sürümlerinde destekleniyor? (Lütfen yanıtınızı düzenleyerek yanıt verin , burada yorumlarda değil (uygunsa). Şimdiden teşekkürler.)
Peter Mortensen

Onaylanan ans'ın neden Wordpress yönetici eklenti sayfasında herhangi bir çıktı göstermediğini bilmiyorum ama bu iyi çalışıyor.
Naimur Hasan

3

Uzun yıllar hep bu formatı kullandım:

<?php
    $data = "Hello";

    function sayHello(){
        echo $GLOBALS["data"];
    }

    sayHello();
?>

Basit ve takip etmesi kolay buluyorum. $ GLOBALS, PHP'nin global bir değişkene başvurmanıza nasıl izin verdiğidir. $ _SERVER, $ _POST, vb. Gibi şeyler kullandıysanız, bilmeden global bir değişkene başvurursunuz.


Hangisi? $GLOBAL(metin) veya $GLOBALS(örnek kod)? (Lütfen yanıtınızı burada yorumlarda değil (uygunsa) düzenleyerek yanıtlayın .)
Peter Mortensen

$ GLOBALS $ GLOBAL değil. Bir "S" olmalı. Ardından değişken adınızı ilişkilendirilebilir diziye bir anahtar gibi referans verin.
Mezmurlar Kalu

Lütfen cevabınızı düzenleyerek güncelleyin ( düzenlemeye başlamak için , "paylaş" ve "bayrak" arasında " düzenle " yi tıklayın . Bu üçü solda - "düzenlenmiş" ve "cevaplandı" nın solunda , yanıttan sonra kendisi, bu yorumun üstünde ve özellikle burada üç yorum). Yorumlardaki bilgiler her an kaybolabilir. Bu bir forum değildir - bilgiler burada güncellenebilir (ve güncellenmelidir) . Şimdiden çok teşekkür ederim.
Peter Mortensen


0
<?php

    $data = 'My data';

    $menugen = function() use ($data) {

        echo "[ $data ]";
    };

    $menugen();
?>

Ayrıca basitleştirebilirsiniz

echo "[" . $data . "]"

-e

echo "[$data]"

echo "[" . $data . "]"ve echo "[ $data ]"aynı değildir (ikincisi için çıktıda iki ekstra boşluk).
Peter Mortensen

0

PHP bu nedenle sinir bozucu olabilir. Yukarıdaki cevaplar globalbenim için işe yaramadı ve doğru kullanımı anlamam biraz zaman aldı use.

Doğru:

$functionName = function($stuff) use ($globalVar) {
 //do stuff
}
$output = $functionName($stuff);
$otherOutput = $functionName($otherStuff);

Bu yanlış:

function functionName($stuff) use ($globalVar) {
 //do stuff
}
$output = functionName($stuff);
$otherOutput = functionName($otherStuff);

Spesifik örneğinizi kullanarak:

    $data = 'My data';

    $menugen = function() use ($data) {
        echo "[" . $data . "]";
    }

    $menugen();

-1

İsterseniz "tanımla" işlevini kullanabilirsiniz, ancak bu işlev tanımlandıktan sonra değiştirilemeyen bir sabit oluşturur.

<?php
    define("GREETING", "Welcome to W3Schools.com!");

    function myTest() {
        echo GREETING;
    }

    myTest();
?>

PHP Sabitleri


Bu, bir değişken değil, global bir sabiti tanımlar.
Beejor

3
Sabitler tanımlandıktan sonra değiştirilemez.
Beejor
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.