إخلاء المسئولية: لن تكشف هذه المقالة عن أي نوع من الوحي لك ولن تفتح العين الثالثة ، لكنها ستسمح لك بفهم السؤال غير الواضح بمزيد من التفاصيل. على الأقل عندما كتبت ذلك ، ساعدتني في ذلك. إذا كنت ذئبًا محنكًا في php ، فلا يمكنك قراءته ، وأعتقد أنه لن يضر الأشخاص ذوي الخبرة بالركض من خلال عيونهم ، وتحديثهم في الذاكرة ، إذا جاز التعبير ، فإن الباقي سيكون طبيعيًا.
لذلك ...
المتغيرات الثابتة في php هي نوع خاص من المتغيرات التي يتم الإعلان عنها باستخدام الكلمة الأساسية الثابتة .
static $foo = 3;
أنها تختلف عن المتغيرات العادية في ذلك (في وقت لاحق في هذه المقالة سيتم النظر في هذه النقاط بمزيد من التفصيل):
- يمكن تعيين الثوابت والتعبيرات الثابتة فقط
- لا يقتصر عمر المتغير الثابت على عمر النطاق الذي تم إعلانه فيه
- يمكن تعريفها في البرنامج النصي مرة واحدة فقط
- لا دمرت حتى نهاية البرنامج النصي
الآن بالترتيب.
1. يمكن تعيين الثوابت والتعبيرات الثابتة فقط
هذا يعني أن نتيجة تشغيل أي وظيفة أو طريقة لا يمكن تعيينها إلى متغير ثابت ، أو بشكل عام أي شيء غير معروف حتى الآن في مرحلة التجميع. وهذا هو ، مثل هذا الإعلان لن يعمل
static $var = foo();
لكن هذا ممكن جدا
static $var = 'some str'; static $varInt = 3 + 5;
2. لا يقتصر عمر المتغير الثابت على عمر النطاق الذي تم إعلانه فيه
سأحاول شرح ما قصدته هنا. ربما سأقدم بعض الأخطاء في المصطلحات ، لكنني سأحاول إيصال الجوهر بأكبر قدر ممكن من الدقة. قارن إلى متغير منتظم. إذا تم الإعلان عن متغير داخل إحدى الوظائف ، فسيكون متغيرًا محليًا ، أي أنه يتم الإعلان عنه في النطاق المحلي (نطاق هذه الوظيفة). في هذه الحالة ، سيكون سياق هذه الوظيفة هو النطاق المحلي. بعد عمل الوظيفة وإرجاع النتيجة ، سيتم إتلاف نطاقها أو سياقها ، مع كل المتغيرات بداخلها.
إذا أعلنا عن متغير ثابت داخل الوظيفة ، فسيتم الإعلان عنه أيضًا في النطاق المحلي ، ولكن لن يكون سياقه هو النطاق المحلي ، ولكن الوظيفة نفسها.
(علاوة على ذلك ، فإن أصعب لحظة في شرحها ، أنقل فقط الجوهر ، بدون تفاصيل ، كيف يتم الإعلان عن الوظائف في php عن مقدار الذاكرة المخصصة لهم وما يكمن في هذه الذاكرة). اتضح بهذه الطريقة ، عندما يتم استدعاء وظيفة ، يقوم المترجم بإنشاء نطاق محلي لها ، ويتم فيه الإعلان عن جميع المتغيرات والوظائف المحلية ، وإلحاقها بسياقها. بإعلان متغير في النطاق المحلي باستخدام static ، يتم تعيين الوظيفة نفسها لهذا المتغير كسياق ، وسيظل هذا المتغير طالما كانت الوظيفة نفسها موجودة. هذا يشبه js عندما تكون الوظيفة كائنًا يمكنك تعيين خصائص وأساليب تعسفية فيه. هنا ، أيضًا ، وظيفة في php هي كائن ليس لـ php ، ولكن للغة أقل.
function echoStaticVar() { static $var = 0; $var++; var_dump($var); }; echoStaticVar();
يمكن ملاحظة أنه بعد انتهاء الوظيفة ، لا يقوم المُجمّع بتدمير المتغير $ var كما يحدث مع المتغير العادي.
وفي ما يلي مثال يوضح بوضوح أن المتغير الثابت ينتمي إلى وظيفة (إما أنه يتم تخزينه في دالة ، أو أن سياقها يمثل وظيفة ، لذلك أنا آسف لأني لا أعرف كيفية تسميتها بشكل صحيح).
$one = function ($i) { static $var = 0; $var += $i; var_dump($var); }; $two = $one; $one(1);
كل شيء يعمل كما هو متوقع ، لأنه عند تعيين دولارين = دولار واحد ؛ لا يتم نسخ الوظيفة نفسها ، ولكن ببساطة كل من هذه المتغيرات سوف تشير إلى نفس منطقة الذاكرة. وفقًا لذلك ، سيكون المتغير الثابت $ var واحدًا لكل من دولار واحد واثنين دولار
نغير المثال قليلاً ، أي أننا لا نسند ، لكننا نستنسخ
$one = function ($i) { static $var = 0; $var += $i; var_dump($var); }; $two = clone($one); $one(1);
الآن اتضح أن $ 1 و $ 2 لا يشيران إلى نفس الوظيفة ذات متغير ثابت $ var ، ولكن إلى وظيفتين مختلفتين تكمنان في مناطق ذاكرة مختلفة ولكل منهما متغير ثابت $ var الخاص به. هذه ليست نقطة واضحة بشكل خاص ، لذلك يمكنك التعثر عليها ، إذا كنت بطبيعة الحال تكتب رمزًا بأسلوب إجرائي ، والذي ربما يعتبر بالفعل شكلًا سيئًا ، لكن هذا غير دقيق).
ما يمكنك القيام به مع هذا هو مثال كلاسيكي لعداد استدعاء دالة.
لكن فيما يتعلق بانتشار OOP في هذا النموذج ، فإن المتغيرات الثابتة نادرة ، حيث إن عليك أن تعمل أساسًا مع الفئات والأساليب (سأكتب مقالة منفصلة حول تنفيذ الاستاتيكية فيها)
3. يمكن تعريفها في البرنامج النصي مرة واحدة فقط
هذا يعني أنه إذا تم الإعلان عن متغير ثابت بالفعل ، وتم تعيين قيمة له ، فلن تقوم التعيينات اللاحقة بالكتابة فوق القيمة المعينة بالفعل ، ولكنها ستقوم بإرجاع المتغير الحالي.
function staticVar($i) { static $var = 0; $var += $i; var_dump($var); }; staticVar(1);
يمكن ملاحظة أنه إذا تمت إعادة تعيين قيمة المتغير الثابت $ var في كل مرة ، فسنحصل دائمًا على النتيجة 1. ولكن بما أنه لم تتم إعادة كتابتها عند إعادة التعيين ، فسنحصل على ما نحصل عليه.
صحيح ، هناك شيء واحد يمكن أن يفسد كل شيء. في إطار وظيفة واحدة (وبشكل أكثر دقة ، في المرة الأولى التي تسمى فيها الوظيفة) ، يمكن إعادة كتابة هذا المتغير عدة مرات كما تريد (في الحالات اللاحقة سيعمل كل شيء كما هو مذكور). بدا لي هذا السلوك غريبًا ومضحكًا ، خاصةً إذا كنت تلعب بأمثلة.
function staticVar($i) { static $var = 0; static $var = 5; $var += $i; var_dump($var); }; staticVar(1);
هنا تم تعيين متغير $ var في الاستدعاء الأول لوظيفة staticVar في السطر الأول ، ثم تم الكتابة فوقه في السطر الثاني. ولكن بالفعل في مكالمات أخرى ، لا في أول أو في السطر الثاني تم إعادة تعيينها ، لكنها أعادت ما كان بالفعل في المكالمة السابقة
function staticVar($i) { static $var = 0;
حتى إذا كان الأمر غريبًا في المكالمة الأولى لـ staticVar في السطر الأول ، فقد تم تعيينها ، ثم في السطر الثاني تم إعادة تعيينها (ولكن دون جدوى) ، ثم تم تنفيذ إجراء إضافة ، وبعد ذلك ، عند محاولة إعادة تعيينها حتى داخل استدعاء الوظيفة الأولى ، قامت بإرجاع المكالمة الموجودة بالفعل معناها.
function staticVarWrong($i) { static $var = 0; static $var = 5; $var += $i; var_dump($var); };
وهذا هو ، اتضح في نفس الأساليب تقريبا ، وسلوك مختلف. علاوة على ذلك ، بناءً على وصف كيفية تصرف المتغيرات الساكنة ، يتم الحصول على النتيجة الصحيحة في staticVarRight . في staticVarWrong ، تبين (بناءً على سلوك الوظيفة) أنه في السطر الثاني من الوظيفة ، تمت إعادة تعريف المتغير.
هذا مسليا لي الكثير جدا.
4. لا يتم تدميرها حتى نهاية البرنامج النصي
لا أرى فائدة كبيرة في شرح هذه النقطة ، خاصة وأن كل شيء واضح من الأمثلة. أثناء تشغيل البرنامج النصي وهناك دالة يتم الإعلان عن متغير ثابت لها ، يوجد هذا المتغير.
كما هو مخطط له ، هذه هي المقالة الأولى عن ساكنة ، قبل OOP ، والحقول الثابتة ، والأساليب.
حسنًا ، بالطبع ، إذا كان هناك شخص على الأقل سيكون مهتمًا وليس من الصعب إلقاء اللوم عليه.