المتغيرات العالمية في PHP لا تعمل كما هو متوقع
سؤال
أواجه مشكلة مع المتغيرات العامة في PHP.انا املك $screen
تم تعيين var في ملف واحد، الأمر الذي يتطلب ملفًا آخر يستدعي ملف initSession()
المحددة في ملف آخر.ال initSession()
يعلن global $screen
ثم يقوم بمعالجة شاشة $ بشكل أكبر باستخدام القيمة المحددة في البرنامج النصي الأول.
كيف يكون هذا ممكنا؟
ولجعل الأمور أكثر إرباكًا، إذا حاولت تعيين $screen مرة أخرى، فاتصل بـ initSession()
, ، فإنه يستخدم القيمة المستخدمة لأول مرة مرة أخرى.سوف يصف التعليمة البرمجية التالية العملية.هل يمكن لأحد أن يشرح هذا؟
$screen = "list1.inc"; // From model.php
require "controller.php"; // From model.php
initSession(); // From controller.php
global $screen; // From Include.Session.inc
echo $screen; // prints "list1.inc" // From anywhere
$screen = "delete1.inc"; // From model2.php
require "controller2.php"
initSession();
global $screen;
echo $screen; // prints "list1.inc"
تحديث:
إذا أعلن $screen
global مرة أخرى قبل طلب النموذج الثاني مباشرةً، يتم تحديث $screen بشكل صحيح لـ initSession()
طريقة.غريب.
المحلول
Global
لا يجعل المتغير عالميًا.أعلم أن الأمر صعب :-)
Global
يقول أنه سيتم استخدام متغير محلي كما لو كان متغيرًا بنطاق أعلى.
على سبيل المثال :
<?php
$var = "test"; // this is accessible in all the rest of the code, even an included one
function foo2()
{
global $var;
echo $var; // this print "test"
$var = 'test2';
}
global $var; // this is totally useless, unless this file is included inside a class or function
function foo()
{
echo $var; // this print nothing, you are using a local var
$var = 'test3';
}
foo();
foo2();
echo $var; // this will print 'test2'
?>
لاحظ أن المتغيرات العالمية نادرًا ما تكون فكرة جيدة.يمكنك كتابة التعليمات البرمجية بنسبة 99.99999% من الوقت بدونها وسيكون الحفاظ على التعليمات البرمجية الخاصة بك أسهل بكثير إذا لم يكن لديك نطاقات غامضة.يتجنب global
إذا استطعت.
نصائح أخرى
global $foo
لا يعني "جعل هذا المتغير عالميًا، حتى يتمكن الجميع من استخدامه". global $foo
وسائل "ضمن نطاق هذه الوظيفة, ، استخدم المتغير العالمي $foo
".
أفترض من المثال الخاص بك أنك تشير في كل مرة إلى $screen من داخل الوظيفة.إذا كان الأمر كذلك سوف تحتاج إلى استخدام global $screen
في كل وظيفة.
تحتاج إلى وضع "شاشة $ عامة" في كل دالة تشير إليها، وليس فقط في أعلى كل ملف.
إذا كان لديك الكثير من المتغيرات التي تريد الوصول إليها أثناء مهمة تستخدم العديد من الوظائف، ففكر في إنشاء كائن "سياق" للاحتفاظ بالأشياء:
//We're doing "foo", and we need importantString and relevantObject to do it
$fooContext = new StdClass(); //StdClass is an empty class
$fooContext->importantString = "a very important string";
$fooContext->relevantObject = new RelevantObject();
doFoo($fooContext);
الآن فقط قم بتمرير هذا الكائن كمعلمة لجميع الوظائف.لن تحتاج إلى متغيرات عامة، وستظل توقيعات وظيفتك نظيفة.من السهل أيضًا استبدال StdClass الفارغ لاحقًا بفئة تحتوي بالفعل على أساليب ذات صلة بها.
يمتد النطاق العام إلى الملفات المضمنة والمطلوبة، ولا تحتاج إلى استخدام الكلمة الأساسية العامة إلا إذا كنت تستخدم المتغير من داخل الوظيفة.يمكنك تجربة استخدام المصفوفة $GLOBALS بدلاً من ذلك.
يجب عليك تعريف المتغير على أنه عالمي قبل تحديد قيم له.
إنه عديم الفائدة حتى يكون في الوظيفة أو الفصل.عالمي يعني أنه يمكنك استخدام متغير في أي جزء من البرنامج.لذا، إذا لم يكن العمومي موجودًا في الوظيفة أو الفئة، فلا فائدة من استخدام العمومي