PHP 7 से पहले "स्ट्रिंग, स्ट्रिंग दी गई" का उदाहरण कैसे दिया जाना चाहिए?


217

यहाँ मेरा कोड है:

function phpwtf(string $s) {
    echo "$s\n";
}
phpwtf("Type hinting is da bomb");

इस त्रुटि के परिणाम कौन से हैं:

बिल्ली के समान घातक त्रुटि: तर्क 1 को phpwtf () के लिए दिया गया स्ट्रिंग, दी गई स्ट्रिंग का एक उदाहरण होना चाहिए

यह पीएचपी को पहचानने और एक ही सांस में वांछित प्रकार को अस्वीकार करने के लिए थोड़ा ओरवेलियन से अधिक है। पाँच बत्तियाँ हैं, लानत है।

PHP में तार के लिए टाइप करने के बराबर क्या है? जवाब पर बोनस विचार जो बताता है कि यहां क्या चल रहा है।


5
ठीक है, ऐसा इसलिए है क्योंकि आप इसे गलत कर रहे हैं। आपका कोड काम करने वाला नहीं है, जिसके साथ शुरू करना है। PHP डॉक्स में टाइप जुगाड़िंग पर पढ़ें। PHP डायनामिक टाइप्ड और कमजोर टाइप्ड है। आप स्ट्रिंग (केवल फ़ंक्शन बॉडी में) के लिए एक तर्क देने के लिए (स्ट्रिंग) का उपयोग कर सकते हैं, लेकिन आप केवल अपने कोड स्निपेट में वस्तुओं और सरणियों को इंगित कर सकते हैं।
रिचर्ड नोप

7
समस्या यह है कि आप एक छोटी सी गलती कर रहे हैं। हैं चार रोशनी!
सीजे डेनिस

@ गॉर्डन, मैंने 5.6 पर परीक्षण किया। फिर भी नसीब नहीं।
पचेरियर

@Pacerier नवीनतम घटनाओं के लिए wiki.php.net/rfc का पालन करें ।
गॉर्डन

3
जाहिर है, स्केलर टाइप-हिंटिंग (जैसा कि ओपी सहज रूप से ऊपर की बात होने की उम्मीद है) अंततः स्रोत के अनुसार PHP * 7 * के लिए एक आरएफसी के तहत अनुमोदित किया गया है । अनुमोदित आरएफसी स्पष्ट रूप से टाइप-चेक रिटर्न-वैल्यू के साथ-साथ मापदंडों (तर्क) के लिए सिंटैक्टिक चीनी भी प्रदान करता है । आने में काफी समय हो गया है।
सेलडोमनैडी

जवाबों:


204

PHP से पहले 7 प्रकार की हिंटिंग का उपयोग केवल वस्तुओं और सरणियों के प्रकारों को बाध्य करने के लिए किया जा सकता है। स्केलर प्रकार प्रकार-संकेत नहीं हैं। इस मामले में कक्षा की एक वस्तु की stringउम्मीद है, लेकिन आप इसे एक (स्केलर) दे रहे हैं string। त्रुटि संदेश मज़ेदार हो सकता है, लेकिन इसे शुरू करने के लिए काम नहीं करना चाहिए। डायनामिक टाइपिंग सिस्टम को देखते हुए, यह वास्तव में किसी प्रकार का विकृत अर्थ बनाता है।

आप केवल मैन्युअल "प्रकार संकेत" अदिश प्रकार:

function foo($string) {
    if (!is_string($string)) {
        trigger_error('No, you fool!');
        return;
    }
    ...
}

1
@ डिसेज़, क्या रिवर्स टाइप हिंटिंग के लिए एक सिंटैक्स है? जैसे कुछ भी लेकिन arrays।
पेसरियर

@ स्पेसर नहीं, वहाँ नहीं है।
deceze

4
यह उत्तर PHP 7 के लिए
जोस नोबेल

24

से पीएचपी मैनुअल :

प्रकार संकेत केवल ऑब्जेक्ट और सरणी (PHP 5.1 के बाद से) प्रकार के हो सकते हैं। इंट और स्ट्रिंग के साथ पारंपरिक प्रकार का संकेत समर्थित नहीं है।

तो आपके पास है। त्रुटि संदेश वास्तव में उपयोगी नहीं है, मैं आपको हालांकि यह देता हूं।

** 2017 संपादित करें **

PHP7 ने अधिक फ़ंक्शन डेटा प्रकार की घोषणाएं पेश कीं, और उपर्युक्त लिंक को फ़ंक्शन तर्क में स्थानांतरित कर दिया गया है: प्रकार की घोषणाएं । उस पेज से:

मान्य प्रकार

  • क्लास / इंटरफ़ेस नाम : पैरामीटर दिए गए वर्ग या इंटरफ़ेस नाम का एक उदाहरण होना चाहिए। (PHP 5.0.0 के बाद से)
  • स्व : पैरामीटर को उसी वर्ग का एक उदाहरण होना चाहिए, जिस पर एक विधि परिभाषित है। यह केवल वर्ग और उदाहरण के तरीकों पर इस्तेमाल किया जा सकता है। (PHP 5.0.0 के बाद से)
  • सरणी : पैरामीटर एक सरणी होना चाहिए। (चूंकि PHP 5.1.0) कॉल करने योग्य है पैरामीटर एक वैध कॉल करने योग्य होना चाहिए। PHP 5.4.0
  • बूल : पैरामीटर बूलियन मान होना चाहिए। (PHP 7.0.0 के बाद से)
  • फ्लोट : पैरामीटर एक फ्लोटिंग पॉइंट नंबर होना चाहिए। (PHP 7.0.0 के बाद से)
  • int : पैरामीटर एक पूर्णांक होना चाहिए। (PHP 7.0.0 के बाद से)
  • स्ट्रिंग : पैरामीटर एक स्ट्रिंग होना चाहिए। (PHP 7.0.0 के बाद से)
  • चलने योग्य : पैरामीटर या तो एक सरणी या एक उदाहरण होना चाहिए ट्रैवर्सेबल। (PHP 7.1.0 के बाद से)

चेतावनी

उपरोक्त स्केलर प्रकारों के लिए उपनाम समर्थित नहीं हैं। इसके बजाय, उन्हें क्लास या इंटरफ़ेस नामों के रूप में माना जाता है। उदाहरण के लिए, बूलियन को एक पैरामीटर या रिटर्न प्रकार के रूप में उपयोग करने के लिए एक तर्क या रिटर्न मान की आवश्यकता होगी जो कि क्लास बूल की बजाय एक उदाहरण वर्ग या इंटरफ़ेस बूलियन है:

<?php
   function test(boolean $param) {}
   test(true);
 ?>

उपरोक्त उदाहरण आउटपुट होगा:

 Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of boolean, boolean given, called in - on line 1 and defined in -:1

अंतिम चेतावनी वास्तव में त्रुटि को समझने के लिए महत्वपूर्ण है "प्रकार का स्ट्रिंग, स्ट्रिंग दिया जाना चाहिए"; चूँकि ज्यादातर केवल वर्ग / इंटरफ़ेस नामों को तर्क प्रकार के रूप में अनुमति दी जाती है, PHP वर्ग नाम "स्ट्रिंग" का पता लगाने की कोशिश करता है, लेकिन इसे कोई भी नहीं ढूँढ सकता क्योंकि यह एक आदिम प्रकार है, इस प्रकार यह अजीब त्रुटि के साथ विफल हो जाता है।


8

PHP आपको "हिंटिंग" की अनुमति देता है जहां आप किसी ऑब्जेक्ट को निर्दिष्ट करने के लिए एक वर्ग की आपूर्ति करते हैं। PHP मैनुअल के अनुसार, "टाइप संकेत केवल ऑब्जेक्ट और सरणी (PHP 5.1 के बाद से) प्रकार के हो सकते हैं। पारंपरिक प्रकार इंट और स्ट्रिंग के साथ संकेत समर्थित नहीं है।" "स्ट्रिंग" की आपकी पसंद के कारण त्रुटि भ्रमित हो रही है - इसके स्थान पर "myClass" डालें और त्रुटि अलग-अलग पढ़ेगी: "phpwtf () के लिए दिया गया तर्क 1 myClass का उदाहरण होना चाहिए, स्ट्रिंग दी गई है"


3

जैसा कि दूसरों ने पहले ही कहा है, वर्तमान में टाइप करना केवल ऑब्जेक्ट प्रकारों के लिए काम करता है। लेकिन मुझे लगता है कि आपके द्वारा ट्रिगर की गई विशेष त्रुटि आगामी स्ट्रिंग प्रकार SplString की तैयारी में हो सकती है ।

सिद्धांत रूप में यह एक स्ट्रिंग की तरह व्यवहार करता है, लेकिन चूंकि यह एक वस्तु है तो ऑब्जेक्ट प्रकार सत्यापन होगा। दुर्भाग्य से यह अभी तक PHP 5.3 में नहीं है, 5.4 में आ सकता है, इसलिए इसने परीक्षण नहीं किया है।


2

पीएचपी 7.0 के रूप में प्रकार घोषणाओं, अदिश प्रकार की अनुमति देते हैं तो इन प्रकार अब उपलब्ध हैं: self, array, callable, bool, float, int, string। पहले तीन PHP 5 में उपलब्ध थे, लेकिन अंतिम चार PHP 7 में नए हैं। यदि आप किसी और चीज (जैसे integerया boolean) का उपयोग करते हैं जिसे एक वर्ग नाम के रूप में व्याख्या किया जाएगा।

अधिक जानकारी के लिए PHP मैनुअल देखें


0

शायद सुरक्षित और सुंदर नहीं, लेकिन अगर आपको यह करना चाहिए:

class string
{
    private $Text;
    public function __construct($value)
    {
        $this->Text = $value;
    }

    public function __toString()
    {
        return $this->Text;
    }
}

function Test123(string $s)
{
    echo $s;
}

Test123(new string("Testing"));

5
मैं अभी भी new string(array(1,2,3))
जिमी टी।

0

मुझे यह त्रुटि तब मिली जब एक Laravel कंट्रोलर से PHP फ़ाइल में एक फंक्शन को इनवाइट किया।

कुछ घंटों के बाद, मुझे यह समस्या मिली: मैं एक स्थैतिक फ़ंक्शन के भीतर से $ का उपयोग कर रहा था ।


Using $this when not in object contextवास्तव में एक गूढ़ संदेश है।
बेन फ्रांसेन

0

(मूल रूप से अपने सवाल में leepowers द्वारा पोस्ट )

त्रुटि संदेश एक बड़े कारण के लिए भ्रमित कर रहा है:

प्राथमिक प्रकार के नाम PHP में आरक्षित नहीं हैं

निम्नलिखित सभी मान्य वर्ग घोषणाएँ हैं:

class string { }
class int { }
class float { }
class double { }

मेरी गलती यह सोचने में थी कि त्रुटि संदेश केवल स्ट्रिंग आदिम प्रकार का उल्लेख कर रहा था - शब्द 'उदाहरण' को मुझे विराम देना चाहिए था। आगे उदाहरण के लिए एक उदाहरण:

class string { }
$n = 1234;
$s1 = (string)$n;
$s2 = new string();
$a = array('no', 'yes');
printf("\$s1 - primitive string? %s - string instance? %s\n",
        $a[is_string($s1)], $a[is_a($s1, 'string')]);
printf("\$s2 - primitive string? %s - string instance? %s\n",
        $a[is_string($s2)], $a[is_a($s2, 'string')]);

आउटपुट:

$ s1 - आदिम स्ट्रिंग? हाँ - स्ट्रिंग उदाहरण? नहीं

$ s2 - आदिम स्ट्रिंग? नहीं - स्ट्रिंग उदाहरण? हाँ

PHP में जब यह वास्तव में एक को छोड़कर stringएक होने के लिए संभव stringहै string। किसी भी भाषा के साथ जो अंतर्निहित प्रकार रूपांतरण का उपयोग करता है, संदर्भ सब कुछ है।


-1

मुझे लगता है कि अंदर ब्लॉक पर php पर टाइपकास्ट करना, PHP पर स्ट्रिंग वस्तु नहीं है जैसा कि मुझे पता है:

<?php
function phpwtf($s) {
    $s = (string) $s;
    echo "$s\n";
}
phpwtf("Type hinting is da bomb");

2
आप फ़ंक्शन में दिए गए अन्य मान को रोकने के लिए अपने फ़ंक्शन के अंदर is_string () सत्यापन जोड़ सकते हैं।
3

1
(string) $sएक $sऐसी वस्तु फेंक सकते हैं , जो एक ऐसी वस्तु है जिसे स्ट्रिंग में नहीं डाला जा सकता है (कोई __toString()विधि लागू नहीं की गई है), इसलिए यह उतना आसान नहीं है
यानिक रोचॉन

हाँ यानिक तुम ठीक कह रहे हो। लेकिन हम इनपुट के सभी को सही स्ट्रिंग के लिए मजबूर नहीं कर सकते हैं? इसलिए अपवाद खेलना आता है। हम मान्यताओं के प्रकार को जोड़ सकते हैं और बाकी के लिए अपवाद पकड़ सकते हैं;)
सबोसिटो

मैं सिर्फ यह कह रहा हूं कि पहले चर की जाँच किए बिना कुछ चर को स्ट्रिंग करने के लिए अगर चर से बचा जा सकता है, मुख्य रूप से क्योंकि अपवादों को पकड़ना महंगा है और खराब डिजाइन पैटर्न / कोडिंग हैबिट्स की ओर जाता है।
यानिक रोचॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.