php - PSR-2 मानक लंबे समय के लिए-यदि शर्तें




convention (6)

संपादित करें

एक साल बाद, मैं दृढ़ता से आपके कोड को फिर से लिखने की सलाह दूंगा यदि एक छोटा बयान हो। चर या फ़ंक्शन कॉल के माध्यम से।

मूल

मैं इस स्थिति में आया, इसलिए मैंने निम्नलिखित प्रारूप के साथ जाने का फैसला किया:

if (
    $a == $b &&
    $b == $c &&
    $c == $d &&
    $g == $d) {
}

लेकिन, मैं phpcbf का उपयोग करता हूं, जो पिछले कोड में (PSR2 मानक का अनुसरण करते हुए) रूपांतरित हुआ:

if ($a == $b &&
    $b == $c &&
    $c == $d &&
    $g == $d) {
}

मैं और जानना चाहता था: यह कैसे पता चलता है कि यह मानक द्वारा अपेक्षित व्यवहार है अगर यह कहीं भी नहीं लिखा गया है? खैर, उत्तर सरल है: मामले को मानक द्वारा ध्यान में रखा जाता है, निम्नलिखित वाक्य द्वारा:

ओपनिंग कोष्ठक के बाद एक स्थान नहीं होना चाहिए

यह बताता है कि दूसरा स्निपेट एक क्यों है, और केवल एक, जो PSR-2 मानक का अनुसरण करता है, जैसा कि php-fig द्वारा घोषित किया गया है।

मुझे इस मामले के लिए कोई मानक नहीं मिला:

if ($a == $b && $b == $c && $c == $d && $g == $d) {

}

या

if (($a == $b && $b == $c) && ($c == $d && $g == $d)) {

}

कल्पना कीजिए कि संस्करण के नाम लंबे हैं और 80 अक्षर पार हो गए हैं। मुझे इसे कैसे नियंत्रित करना चाहिए? ऐसा लग सकता है:

if (
       $a == $b
    && $b == $c
    && $c == $d
    && $g == $d
) {

    }

इस मामले के लिए कोई सिफारिश / सम्मलेन नहीं है, और जैसा कि पहले ही उल्लेख किया गया है कि यह एक बहुत ही असाधारण मामला है।

हालांकि, मापदंडों की एक लंबी सूची के साथ एक फ़ंक्शन कॉल के लिए एक सिफारिश है:

तर्क सूचीबद्ध करता है कि MAY को कई लाइनों में विभाजित किया जा सकता है, जहां प्रत्येक बाद की लाइन एक बार इंडेंट की जाती है। ऐसा करते समय, सूची में पहला आइटम अगली पंक्ति में होना चाहिए, और वहां प्रति पंक्ति केवल एक तर्क होना चाहिए।

<?php
$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);

इसलिए अगर मुझे आपके जैसा ही स्टेटमेंट बनाना है, तो मैं यह करूंगा:

if (
    $a == $b &&
    $b == $c &&
    $c == $d &&
    $g == $d
) {
    // do something
}

जैसा कि आप देख सकते हैं, यह लगभग आपके द्वारा प्रस्तावित समाधान के समान है, लेकिन मैं शर्तों के बाद && ऑपरेटरों को जोड़ना पसंद करता हूं।


मेरी राय में एक अच्छा तरीका कुछ ऐसा करना है

function testString($string)
{
    // define the if criteria
    $criteria = [
        // 0: string starts with A
        substr($string, 0, 1) == 'A',
        // 1: string ends with Z
        substr($string, -1, 1) == 'Z',
        // 2: string length is 10
        strlen($string) == 10
    ];

    // if the array contains false, at leat one creteria failed
    return !in_array(false, $criteria);
}

बेशक, यह बिना रैपर फ़ंक्शन के भी उपयोग किया जा सकता है। यह डिबग करना वास्तव में आसान है: $ मापदंड-चर को केवल var_dump करें, और आपको सूची मिलती है कि क्या सफल हुआ और क्या विफल।

परिणाम

testString('ABCDEFGXYZ')   // true
testString('ABCDEFXYZ')    // false
testString('BCDEFGHXYZ')   // false

यह केवल एक उदाहरण है, इस स्ट्रिंग का पता लगाने जैसे कुछ सरल के लिए, आपको रेगेक्स का उपयोग करना चाहिए।


मैं आपको सुझाव दूंगा कि आप ऑपरेशन के बारे में अलग-अलग शब्दों में सोचने की कोशिश करें। उदाहरण के लिए:

if (count(array_unique([$a, $b, $c, $d, $g])) == 1)

आप शायद पाएंगे कि आप सेट पर एक ऑपरेशन के रूप में पूरे एल्गोरिथ्म को व्यक्त कर सकते हैं, व्यक्तिगत चर के बजाय एक सरणी का उपयोग कर सकते हैं और ऊपर दिखाए गए सेट की तरह तार्किक संचालन का उपयोग कर सकते हैं। यह काफी अलग और अधिक पठनीय कोड को जन्म दे सकता है।

रिफैक्टरिंग का एक और उदाहरण:

namespace My;

UnexpectedValueException::assertAllEqual($a, $b, $c, $d, $g);


class UnexpectedValueException extends \UnexpectedValueException {

    public static function assertAllEqual(/* $value, ... */) {
        $args = func_get_args();
        if (count(array_unique($args)) > 1) {
            throw new static(sprintf('[%s] are not all equal', join(', ', $args)));
        }
    }

}

मैं इसे शुरुआत में पसंद करता हूं:

if (   self::LOG_ALL
    || (    self::DEBUG__EXECUTION_TIME__IS_ENABLED
        && (self::DEBUG__EXECUTION_TIME__THRESHOLD_SECONDS < $trxDurinationSeconds)
       )
) {
    doSomething();
}

मैं लाइन में शुरुआत में मुख्य रूप से पठनीयता और संस्करण नियंत्रण में बेहतर व्यवहार के लिए बयान देता हूं तो मैं लॉजिकल ऑपरेटर्स लगाना पसंद करता हूं।

ध्यान दें कि जैसा कि अन्य उत्तरों में भी उल्लेख किया गया है कि यह आमतौर पर एक कोड गंध है यदि लंबे समय तक बयान हों हालाँकि कभी-कभी आपको यह करना पड़ता है, या कोड पहले से ही है और आप इसे फिर से नहीं लिख सकते हैं, इसलिए यदि यह पहले से ही एक बुरी चीज है तो यह और भी अधिक गड़बड़ नहीं करने में मदद करता है।

इसके अलावा ये बातें अगर केवल एक एकल "और" जहां अलग-अलग तत्वों के लंबे होने पर भी लागू होती हैं, तो आपको इसे कई पंक्तियों में विभाजित करना होगा (उदाहरण के लिए लंबे चर या वर्ग के नाम)।

if (
    $something->getValue() === 'some_value'
    || (
        $something instanceof SomeClass
        && $something->has($someNumber)
        && $someNumber > 42
    )
) {
    // do something
}

पठनीयता : जैसा कि सभी तार्किक ऑपरेटर लंबवत रूप से समूहीकृत होते हैं, आप प्रत्येक पंक्ति में किस ऑपरेटर को देख सकते हैं। जैसा कि आपकी आंख कोड को स्कैन करती है, यह सीधे सीधे खड़ी हो सकती है और इसे केवल वास्तविक अतिरिक्त तार्किक स्तर होने पर क्षैतिज रूप से स्थानांतरित करने की आवश्यकता होती है।

यदि ऑपरेटर्स लाइन के अंत में हैं तो आपकी आंख को असमान लीन की लाइनों के बीच बेतरतीब ढंग से आगे और पीछे बढ़ने की जरूरत है।

संस्करण नियंत्रण में बेहतर व्यवहार : जब स्टेटमेंट के तल पर एक अतिरिक्त क्लॉज जोड़ा जाता है तो यह 1 लाइन में जोड़ा जाता है और संस्करण नियंत्रण में 0 हटा दिया जाता है।

diff --git a/3.php b/3.php
index 367c57c..2a40c3a 100644
--- a/3.php
+++ b/3.php
@@ -6,6 +6,7 @@ 
    if (
         $something instanceof SomeClass
         && $something->has($someNumber)
         && $someNumber > 42
+        && $anotherCase
    ) {
     // do something

यदि आप तार्किक ऑपरेटरों को अंत में रखते हैं तो वह 2 लाइनें जोड़ी जाएंगी और 1 हटा दी जाएगी। यह बदले में उपयोगी जानकारी देता है: अंतिम परिवर्तन के लिए आपका प्रतिबद्ध संदेश दोनों लाइनों के लिए दिखाया जाएगा, जब आप गिट एनोटेट करते हैं, तो आपको उस लाइन के लिए पिछले संदेश पर जाना होगा जहां आपने ऑपरेटर को जोड़ा था।

diff --git a/4.php b/4.php
index f654780..2b9e0c5 100644
--- a/4.php
+++ b/4.php
@@ -5,7 +5,8 @@ 
    if (
        $something instanceof SomeClass &&
        $something->has($someNumber) &&
-       $someNumber > 42
+       $someNumber > 42 &&
+       $anotherCase
     ) {
     // do something






convention