كولد فيوجن:هل من الآمن ترك الكلمة الأساسية للمتغيرات في CFC؟

StackOverflow https://stackoverflow.com/questions/59390

  •  09-06-2019
  •  | 
  •  

سؤال

في مكون ColdFusion (CFC)، هل من الضروري استخدام أسماء مؤهلة بالكامل للمتغيرات ذات النطاق المتغير؟

هل سأضع نفسي في مشكلة إذا قمت بتغيير هذا:

<cfcomponent>
    <cfset variables.foo = "a private instance variable">

    <cffunction name = "doSomething">
        <cfset var bar = "a function local variable">
        <cfreturn "I have #variables.foo# and #bar#.">
    </cffunction>
</cfcomponent>

الى هذا؟

<cfcomponent>
    <cfset foo = "a private instance variable">

    <cffunction name = "doSomething">
        <cfset var bar = "a function local variable">
        <cfreturn "I have #foo# and #bar#.">
    </cffunction>
</cfcomponent>
هل كانت مفيدة؟

المحلول

لن يكون من المهم تحديد "المتغيرات" عند إنشاء المتغير، لأنه سيتم وضع foo في نطاق المتغيرات افتراضيًا؛ولكن سيكون الأمر مهمًا عند الوصول إلى المتغير.

<cfcomponent>
    <cfset foo = "a private instance variable">

    <cffunction name="doSomething">
        <cfargument name="foo" required="yes"/>
        <cfset var bar = "a function local variable">
        <cfreturn "I have #foo# and #bar#.">
    </cffunction>

    <cffunction name="doAnotherThing">
        <cfargument name="foo" required="yes"/>
        <cfset var bar = "a function local variable">
        <cfreturn "I have #variables.foo# and #bar#.">
    </cffunction>

</cfcomponent>

doSomething("args") يُرجع "لدي الحجج و أ دالة المتغير المحلي"

doAnotherThing("args") يُرجع "لدي مثيل خاص للمتغير و أ دالة المتغير المحلي."

نصائح أخرى

سأقول نعم.هل هو ضروري صراحة؟لا.هل يمكنك الإفلات من عدم القيام بذلك؟بالتأكيد.هل تطلب المتاعب؟قطعاً.إذا كان لديك ما يلي داخل دالة cf:

<cfset foo = "bar" />

لن يضع ذلك هذا المتغير في نطاق var المحلي للوظيفة، بل سيضعه في نطاق المتغيرات العالمية لـ CFC، مما يعني أنه متاح لكل طريقة من طرق CFC.هناك أوقات قد ترغب فيها في القيام بذلك، ولكن في معظم الأوقات ستطلب حالة السباق.

عند قراءة أي متغير بواسطة الخادم، إذا لم يتم الإعلان عن هذا المتغير بشكل صريح كجزء من النطاق (طلب، جلسة، وما إلى ذلك) فسيقوم ColdFusion بتشغيل ScopeCheck() لتحديد النطاق الذي يوجد فيه المتغير.لا يؤدي هذا إلى وضع حمل غير ضروري على خادم التطبيق الخاص بك فحسب، بل يقدم أيضًا القدرة على الاختطاف، حيث يكون المتغير الخاص بك في نطاق واحد، ولكن ScopeCheck() عثر على متغير بنفس الاسم أعلى في ترتيب الأسبقية.

دائمًا، دائمًا، دائمًا، نطاق جميع المتغيرات.مهما كانت تافهة.حتى أشياء مثل أسماء الاستعلامات والفهارس المتكررة.أنقذ نفسك ومن يأتي خلفك من الألم.

ومن المهم تحديد النطاق المناسب بشكل خاص في مركبات الكربون الكلورية فلورية."الإسهاب" الإضافي يستحق الوضوح.سيؤدي خروج المتغيرات من نطاقها المقصود إلى حدوث مشكلات خطيرة ويصعب تشخيصها.

الإسهاب ليس دائمًا أمرًا سيئًا.نقوم بتسمية وظائفنا وطرقنا بطرق وصفية مثل getAuthenticatedUser()، بدلاً من gau().من الأفضل ترك أعمدة وجداول قاعدة البيانات وصفية مثل "EmployeePayroll" بدلاً من empprl.وبالتالي، قد يكون الإيجاز "أسهل" عندما تكون ذاكرتك قصيرة المدى مليئة بتفاصيل المشروع، لكن كونك وصفيًا يوضح نيتك ويكون مفيدًا أثناء مرحلة صيانة التطبيق، بعد فترة طويلة من امتلاء ذاكرتك قصيرة المدى بأشياء أخرى .

الإجابة المختصرة على سؤالك هي أنه لا، ربما لن تواجه مشكلة في محاولة القيام بذلك.خارج سياق UDF (حتى داخل CFC)، تتضمن عبارة المجموعة غير المحددة نطاق المتغيرات.

بالإضافة إلى ذلك، في CFC، يكون نطاق المتغيرات متاحًا لجميع وظائفه؛إنه نوع من النطاق العام ضمن CFC - يشبه النطاق "هذا"، باستثناء نطاق المتغيرات الذي يشبه المتغيرات "الخاصة"، في حين أن هذا النطاق يشبه المتغيرات العامة.

لاختبار ذلك، قم بإنشاء test.cfc:

<cfcomponent>
    <cfset foo = "bar" />
    <cffunction name="dumpit" output="true">
        <cfdump var="#variables#" label="cfc variables scope">
        <cfdump var="#this#" label="cfc this scope">
    </cffunction>
</cfcomponent>

وصفحة لاختباره، test.cfm:

<cfset createObject("component", "test").dumpit() />

وستكون النتائج:


الآن، لمعالجة مشكلة أخرى أراها في رمز المثال الخاص بك...

في CF، جميع الوظائف المحددة من قبل المستخدم لها نطاق خاص غير مسمى يشار إليه عادةً باسم النطاق "var".إذا قمت بما يلي داخل UDF:

<cfset foo = "bar" />

ثم تطلب من CF وضع هذا المتغير في نطاق var.

لتركيب الأشياء قليلاً، يمكن أن تواجه مشكلات (تتغير القيم المتغيرة عندما لا تتوقعها) عندما تكون كذلك لا باستخدام نطاق var في UDFs المضمنة الخاصة بك.

لذا فإن القاعدة الأساسية هي دائمًا، دائمًا، دائمًا، دائماً var-نطاق المتغيرات الداخلية الخاصة بك (بما في ذلك أسماء الاستعلام).هناك أداة تسمى varScoper سيساعدك ذلك في العثور على المتغيرات التي تحتاج إلى نطاق var.آخر مرة تأكدت من أنها لم تكن مثالية، لكنها بالتأكيد البداية.

ومع ذلك، فهو أ سيء فكرة الإشارة إلى متغيرات (عرض/استخدام) بدون نطاق (باستثناء المتغيرات ذات النطاق var، حيث لا يمكنك تحديد النطاق للقراءة منه) في CFCs أو حتى على صفحات CFM القياسية الخاصة بك.اعتبارًا من CF7، كان هناك 9 نطاقات تم فحصها بترتيب معين عندما تقرأ متغيرًا دون تحديد النطاق، والمطابقة الأولى هي التي تفوز.مع CF8، يمكن أن يكون هناك المزيد من النطاقات في تلك القائمة، لم أتحقق منها.عند القيام بذلك، فإنك تخاطر بالحصول على قيمة من نطاق واحد عندما تتوقعها من نطاق آخر؛وهو كابوس لتصحيح الأخطاء ...أؤكد لك.;)

لذلك باختصار: مما يعني نطاق المتغير (في المجموعة) ليس فكرة سيئة (على الرغم من أنني عادةً ما أحدده على أي حال)؛لكن الاستدلال نطاق المتغير (عند القراءة) يسأل عن المتاعب.

قد لا ينجح تحديد النطاق بشكل صريح في نطاق المتغيرات، ولكنها ليست فكرة جيدة، وبصراحة السبب الوحيد لا لهو من الكسل المنظمة البحرية الدولية.إذا قمت بنطاق كل شيء بشكل صريح 1) فإنك تتجنب المشكلات المحتملة، و2) يجعل قراءة التعليمات البرمجية أسهل لأنه لا يوجد شك في النطاق الذي توجد فيه الأشياء.

بالنسبة لي، هذا لا يجعل الكود أكثر تفصيلًا (وبالتأكيد ليس مطولًا بلا داعٍ) - فهو في الواقع أسهل في القراءة، ويتجنب الارتباك، ويتجنب الآثار الجانبية الغريبة التي قد تظهر إذا لم تقم بتحديد النطاق بشكل صريح.

الجواب البسيط على سؤالك هو:"لا، ليس من الضروري"

ومع ذلك، أعتقد أن أفضل الممارسات تقترح عليك، في الواقع، استخدام مُعرف المتغيرات عند الوصول إلى تلك المتغيرات.في رأيي، أي شخص يأتي إلى الكود الخاص بك في المستقبل، ويبحث في منتصف الوظيفة، سيعرف على الفور نطاق المتغير دون الحاجة إلى مسح الجزء العلوي من الوظيفة للوظائف المحلية.

في الواقع، أقوم بإضافة القليل من الإسهاب إلى وحدات CFC UDF الخاصة بي عن طريق إنشاء بنية محلية واحدة:

<cfset var local = structNew() />

ثم أضع جميع المتغيرات المحلية الخاصة بي في تلك البنية وأشير إليها بهذه الطريقة حتى يبدو الكود الخاص بي كما يلي:

<cfset local.foo =variables.bar + 10 />

بعد قراءة إجاباتك إليك ما أفكر فيه:

نعم، أنها آمنة.بشكل عام، ليس من الضروري أو المفيد تحديد نطاق المتغيرات بشكل صريح.إنه يضيف فقط فوضى إلى لغة مطولة بالفعل.

من المؤكد أن هناك استثناءً بسيطًا واحدًا، وهو سولدارنال وأشار، حيث مطلوب تأهيل متغير نطاق المتغيرات.هذا إذا كان لديك متغير دالة محلي بنفس الاسم.(ولكن ربما لا ينبغي عليك فعل ذلك على أي حال.)

وبغض النظر عن أفضل الممارسات، أعتقد أن الأمر قد يعتمد أيضًا على كيفية وصولك إلى ملفات cfc الخاصة بك، ولم أواجه أية مشكلات في تركها خارجًا عند إنشاء الكائنات والوصول إليها من الانصهار البارد.ومع ذلك أعتقد أنه قد تكون هناك حاجة إليها عند الوصول إليها و/أو تعيينها عن بعد عبر actionscript في flex/flash.

وهنا جيدة جدا مرجع نطاق مركبات الكربون الكلورية فلورية من ريموند كامدن.أنا شخصياً أفضل عمل تجزئة "ذاتية" لتجنب كل الالتباس (لاحظ أنني لا أستخدم نطاق "المتغيرات" في الوظائف):

<cfcomponent>
  <cfset variables.self = structNew()>
  <cfscript>
    structInsert(variables.self, <key>, <value>);
    ...
  </cfscript>

  <cffunction name="foo">
    self.<key> = <value>
    <cfreturn self.<key> />
  </cffunction>

  ...
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top