PHPDoc ऑब्जेक्ट्स की सरणी के लिए इशारा करते हैं?


417

इसलिए, PHPDoc में एक @varसदस्य चर घोषणा से ऊपर निर्दिष्ट कर सकता है ताकि उसके प्रकार का संकेत दिया जा सके। फिर एक आईडीई, पूर्व के लिए। PHPEd, यह जानता होगा कि वह किस प्रकार की वस्तु के साथ काम कर रहा है और उस चर के लिए एक कोड अंतर्दृष्टि प्रदान करने में सक्षम होगा।

<?php
  class Test
  {
    /** @var SomeObj */
    private $someObjInstance;
  }
?>

जब तक मैं उन वस्तुओं के माध्यम से एक उचित संकेत प्राप्त करने में सक्षम होने के लिए वस्तुओं की एक सरणी के समान करने की आवश्यकता है, तब तक यह बहुत अच्छा काम करता है।

तो, क्या यह निर्दिष्ट करने के लिए PHPDoc टैग घोषित करने का एक तरीका है कि सदस्य चर एस की एक सरणी है SomeObj? @varसरणी पर्याप्त नहीं है, और @var array(SomeObj)उदाहरण के लिए मान्य नहीं लगती है।


2
इस Netbeans 6.8 देव ब्लॉग में कुछ संदर्भ है कि IDE अब सरणी के सदस्यों के प्रकार को कम करने के लिए पर्याप्त स्मार्ट है: blogs.sun.com/netbeansphp/entry/php_templates_improved
John

3
@therefromhere: आपका लिंक टूट गया है। मुझे लगता है कि नया URL है: blogs.oracle.com/netbeansphp/entry/php_templates_improved
DanielaWranie

मेरे जैसे लोगों के लिए, एक उत्तर देना और खोज करना: यदि आप PHPStorm का उपयोग करते हैं, तो सबसे अधिक मतदान वाले उत्तर को देखें: इसका एक विशिष्ट संकेत है! stackoverflow.com/a/1763425/1356098 (इसका मतलब यह नहीं है कि यह ओपी के लिए जवाब होना चाहिए, क्योंकि वह PHPEd के लिए पूछ रहा है, उदाहरण के लिए)
एरेनोर पाज़

जवाबों:


337

उपयोग:

/* @var $objs Test[] */
foreach ($objs as $obj) {
    // Typehinting will occur after typing $obj->
}

जब इनलाइन वैरिएबल टाइप करना, और

class A {
    /** @var Test[] */
    private $items;
}

वर्ग गुणों के लिए।

'09 से पिछला उत्तर जब PHPDoc (और Zend Studio और Netbeans की तरह IDE) के पास वह विकल्प नहीं था:

सबसे अच्छा आप कह सकते हैं,

foreach ($Objs as $Obj)
{
    /* @var $Obj Test */
    // You should be able to get hinting after the preceding line if you type $Obj->
}

मैं Zend स्टूडियो में बहुत कुछ करता हूं। अन्य संपादकों के बारे में नहीं जानते, लेकिन यह काम करना चाहिए।


3
यह समझ में आता है, लेकिन यह 5.2 PHPEd के लिए काम नहीं किया। केवल एक चीज जो मैं काम करने में सक्षम था, वह है फॉर्च्यूनर ($ Objs as / ** @var Test * / $ Obj), जो बहुत ही बदसूरत है। :(
आर्टेम रसाकोवस्की

14
Netbeans 7 में ध्यान दें, लगता है कि आपके पास केवल एक तारांकन महत्वपूर्ण है - /** @var $Obj Test */काम नहीं करता है।
कंट्रेबिस

3
@ कॉन्ट्रेबिस: "@वर" एक वैध डॉकब्लॉक टैग है। इसलिए भले ही आपका IDE किसी डॉकब्लॉक "/ ** ... /" का समर्थन नहीं करता है और केवल "/ ... * " में "@var" का समर्थन करता है - कृपया, कृपया अपना सही डॉकब्लॉक न बदलें। अपने IDE के बग ट्रैकर के लिए एक समस्या दर्ज करें जो आपके IDE को मानकों के अनुरूप बनाता है। अपनी विकास टीम की कल्पना करें / बाहरी डेवलपर्स / समुदाय अलग-अलग आईडीई का उपयोग करता है। इसे वैसे ही रखें और भविष्य के लिए तैयार रहें।
डैनियलवेर्नी

181
सुनिश्चित करें कि आप नीचे देखें! मैं लगभग नीचे स्क्रॉल नहीं किया - बड़ा मिस्टेक होगा !!! कई आईडीई बेहतर सिंटैक्स का समर्थन करेंगे! (संकेत: @var Object[] $objectsकहते हैं कि "$ ऑब्जेक्ट्स" ऑब्जेक्ट के उदाहरणों की एक सरणी है।)
थॉम पोर्टर

10
/** @var TYPE $variable_name */सही वाक्यविन्यास है; प्रकार और चर नाम के क्रम को उल्टा न करें (जैसा कि टिप्पणियों में पहले सुझाव दिया गया है) क्योंकि सभी मामलों में काम नहीं करेगा।
srcspider

893

JetBrains से PhpStorm IDE में, आप उपयोग कर सकते हैं /** @var SomeObj[] */, जैसे:

/**
 * @return SomeObj[]
 */
function getSomeObjects() {...}

Phpdoc प्रलेखन इस विधि की सिफारिश की:

एक प्रकार से निर्दिष्ट, प्रकार परिभाषा प्रत्येक सरणी तत्व के प्रकार के पाठक को सूचित करती है। केवल एक प्रकार फिर किसी दिए गए सरणी के लिए तत्व के रूप में अपेक्षित है।

उदाहरण: @return int[]


10
मैंने अभी डाउनलोड किया है और पिछले एक सप्ताह से phpstorm का उपयोग कर रहा हूं। एप्टाना के बाहर बिल्ली को मारता है (जो मुक्त होने के लिए महान है)। यही वह है जिसकी तलाश में मैं हूं। वास्तव में, यह उसी तरह है जैसे आप इसे जावास्क्रिप्ट के लिए करेंगे, मुझे अनुमान लगाना चाहिए था
जुआन मेंडेस

3
धन्यवाद दोस्त! यही वह है जिसकी तलाश में मैं हूं। PHPStorm शानदार है।
एरिक शियरबॉम

5
यह नेटबीन में काम नहीं करता है, मैं निराश हूं। Jetbrains कुछ बहुत अच्छे उपकरण बनाते हैं।
कीओ

10
@fishbone @Keyo अब नेटबीन्स में काम करता है (7.1 रात में कम से कम, शायद पहले का निर्माण), हालांकि ऐसा लगता है कि आपको एक अस्थायी चर (बग?) का उपयोग करने की आवश्यकता है। के लिए इशारा foreach(getSomeObjects() as $obj)काम नहीं करता है, लेकिन यह के लिए करता है$objs = getSomeObjects(); foreach($objs as $obj)
जॉन कार्टर

2
@var Obj[string]साहचर्य सरणियों के लिए अच्छा होगा ।
donquixote

59

नेटबीन के संकेत:

आपको उपयोगकर्ता कक्षाओं की एक सरणी के $users[0]->लिए कोड पूर्णता प्राप्त $this->होती है।

/**
 * @var User[]
 */
var $users = array();

जब आप पूरा कर लेते हैं तो आप वर्ग के सदस्यों की सूची में सरणी का प्रकार भी देख सकते हैं $this->...


4
PhpStorm 9 EAP में भी काम करता है: / ** * @ उपयोगकर्ता UserInterface [] * / var $ उपयोगकर्ताओं = []; // एक इंटरफेस को लागू करने वाले ओआरजे का एरेना
रॉनन

मैंने इसे NetBeans IDE 8.0.2 में आज़माया है, लेकिन मुझे कक्षा में इस समय मेरे द्वारा सुझाए गए सुझाव मिलते हैं।
Wojciech Jasi'ski

यह भी ग्रहण 4.6.3 में काम करता है (आईडी क्या संस्करण समर्थन शुरू किया गया था, लेकिन इसके काम कर रहा है, और अब मैं इसका क्या उपयोग कर रहा हूं)
hanshenrik

यह दुर्भाग्य से array_pop()किसी कारण से या इसी तरह के कार्यों का उपयोग करने के बाद काम नहीं करता है । लगता है कि Netbeans उन कार्यों को महसूस नहीं करता है जो इनपुट ऐरे के किसी एक तत्व को वापस करते हैं।
विलियम डब्ल्यू

29

एक चर निर्दिष्ट करने के लिए वस्तुओं का एक सरणी है:

$needles = getAllNeedles();
/* @var $needles Needle[] */
$needles[1]->...                        //codehinting works

यह Netbeans 7.2 में काम करता है (मैं इसका उपयोग कर रहा हूँ)

इसके साथ भी काम करता है:

$needles = getAllNeedles();
/* @var $needles Needle[] */
foreach ($needles as $needle) {
    $needle->...                        //codehinting works
}

इसलिए अंदर घोषणा का उपयोग foreachआवश्यक नहीं है।


2
यह समाधान मेरे विचार में स्वीकृत उत्तर की तुलना में क्लीनर है, क्योंकि आप कई बार फॉर्च्यूनर का उपयोग कर सकते हैं और /* @var $Obj Test */हर बार एक नए एनोटेशन के साथ काम करना जारी रखेगा ।
हेनरी

मैं यहां दो मुद्दे देखता हूं: 1. उचित phpdoc /** 2 के साथ शुरू होता है सही प्रारूप है@var <data-type> <variable-name>
ईसाई

@Christian 1: मुख्य प्रश्न phpdoc नहीं है, लेकिन टाइप 2 है: सही प्रारूप जैसा आप कहते हैं, वैसा अन्य उत्तरों के अनुसार भी नहीं है। वास्तव में, मैं आपकी टिप्पणी के साथ 2 मुद्दे देखता हूं, और मैं सोच रहा हूं कि आप सही प्रारूप के साथ अपना जवाब क्यों देते हैं
हाईमास्टडन

1. टाइपिंग के साथ काम करता है phpdoc ... यदि आप डॉकब्लॉक का उपयोग नहीं करते हैं, तो आपका आईडीई यह अनुमान लगाने की कोशिश नहीं करेगा कि आपने कुछ यादृच्छिक टिप्पणी में क्या लिखा है। 2. सही प्रारूप, जैसा कि कुछ अन्य जवाबों में भी कहा गया है कि मैंने ऊपर क्या निर्दिष्ट किया है; चर नाम से पहले डेटा प्रकार3. मैंने एक और उत्तर नहीं लिखा क्योंकि प्रश्न को दूसरे की आवश्यकता नहीं है और मैं आपके कोड को संपादित नहीं करूंगा।
ईसाई

24

PSR-5: PHPDoc जेनरिक-शैली संकेतन का एक रूप प्रस्तावित करता है।

वाक्य - विन्यास

Type[]
Type<Type>
Type<Type[, Type]...>
Type<Type[|Type]...>

एक संग्रह में मान भी एक और सरणी और यहां तक ​​कि एक और संग्रह हो सकता है।

Type<Type<Type>>
Type<Type<Type[, Type]...>>
Type<Type<Type[|Type]...>>

उदाहरण

<?php

$x = [new Name()];
/* @var $x Name[] */

$y = new Collection([new Name()]);
/* @var $y Collection<Name> */

$a = new Collection(); 
$a[] = new Model_User(); 
$a->resetChanges(); 
$a[0]->name = "George"; 
$a->echoChanges();
/* @var $a Collection<Model_User> */

नोट: यदि आप एक IDE से कोड सहायता करने की अपेक्षा कर रहे हैं, तो यह एक और सवाल है कि क्या IDE PHPDoc जेनेरिक-शैली संग्रह संकेतन का समर्थन करता है।

मेरे इस सवाल के जवाब से ।


जेनरिक नोटेशन को PSR-5 से हटा दिया गया
9

11

मैं रॉबर्ट सी। मार्टिन द्वारा "क्लीन कोड" में उल्लिखित - स्वच्छ कोड पढ़ना और लिखना पसंद करता हूं। जब आप अपने क्रेडेंशियल का पालन कर रहे हों, तो आपको अपने एरे के स्ट्रक्चर (आंतरिक) को जानने के लिए डेवलपर (आपके एपीआई के उपयोगकर्ता के रूप में) की आवश्यकता नहीं होनी चाहिए।

एपीआई उपयोगकर्ता पूछ सकता है: क्या केवल एक आयाम वाला एक सरणी है? क्या वस्तुएं एक बहुआयामी सरणी के सभी स्तरों पर चारों ओर फैली हुई हैं? कितने नेस्टेड लूप (फोरचेक, आदि) मुझे सभी वस्तुओं तक पहुंचने की आवश्यकता है? उस सरणी में किस प्रकार की वस्तुएं "संग्रहीत" हैं?

जैसा कि आपने उल्लिखित किया है कि आप उस सरणी का उपयोग करना चाहते हैं (जिसमें वस्तुएं हैं) एक आयामी सरणी के रूप में।

निशि द्वारा उल्लिखित के रूप में आप उपयोग कर सकते हैं:

/**
 * @return SomeObj[]
 */

उसके लिए।

लेकिन फिर से: जागरूक रहें - यह एक मानक डॉकब्लॉक नोटेशन नहीं है। यह नोटेशन कुछ IDE उत्पादकों द्वारा पेश किया गया था।

ठीक है, ठीक है, एक डेवलपर के रूप में आप जानते हैं कि "[]" PHP में एक सरणी से बंधा है। लेकिन सामान्य PHP संदर्भ में "कुछ []" का क्या अर्थ है? "[]" का अर्थ है: "कुछ" के भीतर नया तत्व बनाना। नया तत्व सब कुछ हो सकता है। लेकिन आप जो व्यक्त करना चाहते हैं वह है: एक ही प्रकार की वस्तुओं की सरणी और यह सटीक प्रकार है। जैसा कि आप देख सकते हैं, आईडीई निर्माता एक नया संदर्भ प्रस्तुत करता है। एक नया संदर्भ जो आपको सीखना था। एक नया संदर्भ अन्य PHP डेवलपर्स को सीखना था (अपने डॉकब्लॉक्स को समझने के लिए)। खराब शैली (!)।

क्योंकि आपके सरणी में एक आयाम है जिसे आप शायद "ऑब्जेक्ट की सरणी" को "सूची" कहना चाहते हैं। ज्ञात हो कि "सूची" का अन्य प्रोग्रामिंग भाषाओं में एक बहुत ही विशेष अर्थ है। उदाहरण के लिए इसे "संग्रह" कहना बेहतर होगा।

याद रखें: आप एक प्रोग्रामिंग भाषा का उपयोग करते हैं जो आपको OOP के सभी विकल्पों में सक्षम बनाती है। एक सरणी के बजाय एक वर्ग का उपयोग करें और अपनी कक्षा को एक सरणी की तरह ट्रैवर्सेबल बनाएं। उदाहरण के लिए:

class orderCollection implements ArrayIterator

या यदि आप एक बहुआयामी सरणी / ऑब्जेक्ट संरचना में विभिन्न स्तरों पर आंतरिक वस्तुओं को संग्रहीत करना चाहते हैं:

class orderCollection implements RecursiveArrayIterator

यह समाधान आपके सरणी को "ऑर्डरकॉलक्शन" के प्रकार से बदल देता है, लेकिन अब तक आपके आईडीई के भीतर कोड पूरा करने में सक्षम नहीं है। ठीक है। अगला कदम:

Docblocks के साथ इंटरफेस द्वारा पेश किए गए तरीकों को लागू करें - विशेष:

/**
 * [...]
 * @return Order
 */
orderCollection::current()

/**
 * [...]
 * @return integer E.g. database identifier of the order
 */
orderCollection::key()

/**
 * [...]
 * @return Order
 */
orderCollection::offsetGet()

इसके लिए टाइपिंग का उपयोग करना न भूलें:

orderCollection::append(Order $order)
orderCollection::offsetSet(Order $order)

यह समाधान बहुत कुछ शुरू करता है:

/** @var $key ... */
/** @var $value ... */

सभी कोड फ़ाइलों पर (जैसे छोरों के भीतर), जैसा कि ज़ाहिमाका ने उसके / उसके जवाब की पुष्टि की है। आपका API उपयोगकर्ता उस डॉकब्लॉक को लागू करने के लिए मजबूर नहीं होता है, जिसके पास कोड पूरा होने के लिए है। केवल एक जगह पर @return होने से अतिरेक (@var) को यथासंभव कम कर देता है। "DvarBlocks with @var" को छिड़कना आपके कोड को सबसे अधिक पठनीय बना देगा।

फाइनली आप हो गए। मुश्किल से हासिल होता है? लगता है कि एक अखरोट को तोड़ने के लिए स्लेजहैमर ले रहा है? वास्तव में नहीं, क्योंकि आप उस इंटरफेस से और साफ कोड से परिचित हैं। याद रखें: आपका स्रोत कोड एक बार लिखा गया है / कई पढ़ा गया है।

यदि आपके आईडीई का कोड पूरा होने पर इस दृष्टिकोण के साथ काम नहीं किया जाता है, तो बेहतर तरीके से स्विच करें (जैसे इंटेलीजे आईडीईए, पीएचपीओआरएम, नेटबीन्स) या अपने आईडीई निर्माता के समस्या ट्रैकर पर एक सुविधा अनुरोध दर्ज करें।

मेरे ट्रेनर होने और मुझे इतना बढ़िया सामान सिखाने के लिए क्रिश्चियन वीस (जर्मनी से) को धन्यवाद। पुनश्च: मुझे और उसे XING पर मिलो।


यह "सही" तरीके से दिखता है, लेकिन मुझे यह नेटबिन के साथ काम करने के लिए मिलता है। एक छोटा सा उदाहरण बनाया: imgur.com/fJ9Qsro
fehrlich

2
शायद 2012 में यह "एक मानक नहीं" था, लेकिन अब इसे phpDoc की अंतर्निहित कार्यक्षमता के रूप में वर्णित किया गया है।
वीरोन

@Irone ऐसा लगता है कि phpDocumentor इसे ide निर्माताओं की प्रतिक्रिया के रूप में अपने मैनुअल में जोड़ता है। यहां तक ​​कि अगर आपके पास एक विस्तृत उपकरण समर्थन है, तो इसका मतलब यह नहीं है कि यह सबसे अच्छा अभ्यास है। यह शुरू होता है SomeObj [] अधिक से अधिक परियोजनाओं में चारों ओर फैल गया, आवश्यकता के समान, requirement_once, शामिल करें और शामिल करें सालों पहले किया था। ऑटोलॉडिंग के साथ उस स्टेटमेंट की उपस्थिति 5% से कम हो जाती है। उम्मीद है कि SomeObj [] ऊपर के दृष्टिकोण के पक्ष में अगले 2 वर्षों के भीतर समान दर पर गिरता है।
डेनिएलावेरी जूल

1
मुझे समझ में नहीं आता क्यों? यह बहुत ही सरल और स्पष्ट अंकन है। जब आप देखते SomeObj[]हैं कि यह SomeObjउदाहरणों का द्वि-आयामी सरणी है और तब आप जानते हैं कि इसके साथ क्या करना है। मुझे नहीं लगता कि यह "क्लीन कोड" क्रेडो का पालन नहीं करता है।
विरोने

इसका उत्तर होना चाहिए। हालांकि, सभी लोगों के @return <className>लिए सभी आईडीई समर्थन दृष्टिकोण नहीं है current()। PhpStorm समर्थन करता है तो इसने मुझे बहुत मदद की। धन्यवाद दोस्त!
पावेल

5

array[type]Zend Studio में उपयोग करें ।

Zend स्टूडियो में, array[MyClass]या array[int]या यहां तक कि array[array[MyClass]]काम महान।


5

NetBeans 7.0 में (आप बहुत कम हो सकते हैं) आप रिटर्न प्रकार "टेक्स्ट ऑब्जेक्ट्स के साथ सरणी" घोषित कर सकते हैं जैसे @return Textऔर कोड हिंटिंग काम करेगा:

संपादित करें: @ याकूब के सुझाव के साथ उदाहरण को अद्यतन किया

/**
 * get all Tests
 *
 * @return Test|Array $tests
 */
public function getAllTexts(){
    return array(new Test(), new Test());
}

और बस इसका उपयोग करें:

$tests =  $controller->getAllTests();
//$tests->         //codehinting works!
//$tests[0]->      //codehinting works!

foreach($tests as $text){
    //$test->      //codehinting works!
}

यह सही नहीं है, लेकिन यह बेहतर है कि इसे सिर्फ "मिश्रित" छोड़ने के लिए, जो कोई मूल्य नहीं लाता है।

कान्स आपको पाठ ऑब्जेक्ट के रूप में सरणी को चलाने की अनुमति है जो त्रुटियों को फेंक देगा।


1
मैं "@ ग्रेट सरणी का उपयोग करता हूं। कुछ विवरण का परीक्षण करें।" जो एक ही व्यवहार को ट्रिगर करता है लेकिन थोड़ा अधिक व्याख्यात्मक है।
बॉब फांगर

1
यह एक समाधान है , समाधान नहीं है। आप यहां कह रहे हैं "यह फ़ंक्शन प्रकार 'टेस्ट', या एक सरणी का एक ऑब्जेक्ट लौटा सकता है"। हालाँकि यह तकनीकी रूप से आपको कुछ भी नहीं बताता है कि सरणी में क्या हो सकता है।
Byson

5

DanielaWaranie उसके जवाब में उल्लेख किया है - वहाँ $ आइटम का प्रकार निर्दिष्ट करने का एक तरीका है जब आप $ collectionObject में $ से अधिक आइटम पुनरावृत्ति: जोड़े @return MyEntitiesClassNameके लिए current()और के आराम Iteratorऔर ArrayAccess-methods जो बदले मूल्यों।

बूम! /** @var SomeObj[] $collectionObj */ओवर foreachऑब्जेक्ट की आवश्यकता नहीं है , और संग्रह ऑब्जेक्ट के साथ सही काम करता है, जैसा कि वर्णित विशिष्ट विधि के साथ संग्रह को वापस करने की आवश्यकता नहीं है @return SomeObj[]

मुझे संदेह है कि सभी आईडीई इसे समर्थन नहीं करते हैं, लेकिन यह PhpStorm में पूरी तरह से ठीक काम करता है, जिससे मुझे खुशी मिलती है।

उदाहरण:

class MyCollection implements Countable, Iterator, ArrayAccess {

    /**
     * @return User
     */
    public function current() {
        return $this->items[$this->cursor];
    }

    //... implement rest of the required `interface` methods and your custom
}

क्या उपयोगी मैं इस जवाब पोस्टिंग जोड़ने जा रहा था

मेरे मामले में current()और बाकी interface-methods को Abstract-collection class में लागू किया गया है और मुझे नहीं पता कि किस तरह की संस्थाओं को अंततः संग्रह में संग्रहीत किया जाएगा।

तो यहाँ यह चाल है: अमूर्त वर्ग में रिटर्न टाइप निर्दिष्ट न करें, इसके बजाय @methodविशिष्ट संग्रह वर्ग के विवरण में PhDDoc इंस्ट्रक्शन का उपयोग करें ।

उदाहरण:

class User {

    function printLogin() {
        echo $this->login;
    }

}

abstract class MyCollection implements Countable, Iterator, ArrayAccess {

    protected $items = [];

    public function current() {
        return $this->items[$this->cursor];
    }

    //... implement rest of the required `interface` methods and your custom
    //... abstract methods which will be shared among child-classes
}

/**
 * @method User current()
 * ...rest of methods (for ArrayAccess) if needed
 */
class UserCollection extends MyCollection {

    function add(User $user) {
        $this->items[] = $user;
    }

    // User collection specific methods...

}

अब, कक्षाओं का उपयोग:

$collection = new UserCollection();
$collection->add(new User(1));
$collection->add(new User(2));
$collection->add(new User(3));

foreach ($collection as $user) {
    // IDE should `recognize` method `printLogin()` here!
    $user->printLogin();
}

एक बार फिर: मुझे संदेह है कि सभी आईडीई इसका समर्थन नहीं करते, लेकिन PhpStorm करता है। तुम्हारा प्रयास, परिणाम टिप्पणी में पोस्ट!


वाउचर को इसे आगे बढ़ाने के लिए, लेकिन दुर्भाग्य से मैं अभी भी अपने आप को अच्छे पुराने जावा जेनेरिक प्रकारों को बदलने के लिए एक संग्रह के विशेषज्ञ के लिए हल कर सकता हूं .... yuck '
सेबास

धन्यवाद। आप एक स्थिर विधि कैसे टाइप कर सकते हैं?
येवगेनी अफानसेयेव

3

मुझे पता है कि मुझे पार्टी में देर हो रही है, लेकिन मैं हाल ही में इस समस्या पर काम कर रहा हूं। मुझे आशा है कि कोई इसे देखता है क्योंकि स्वीकृत उत्तर, हालांकि सही है, सबसे अच्छा तरीका नहीं है जो आप ऐसा कर सकते हैं। कम से कम PHPStorm में नहीं, मैंने NetBeans का परीक्षण नहीं किया है।

सबसे अच्छा तरीका देशी सरणी प्रकारों का उपयोग करने के बजाय ArrayIterator वर्ग का विस्तार करना शामिल है। यह आपको एक उदाहरण-स्तर के बजाय एक वर्ग-स्तर पर संकेत टाइप करने की अनुमति देता है, जिसका अर्थ है कि आपको केवल एक बार PHPDoc करना होगा, आपके कोड में नहीं (जो न केवल गन्दा है और DRY का उल्लंघन करता है, बल्कि जब यह आता है तो समस्याग्रस्त भी हो सकता है। Refactoring - PHPStorm की याद आती है PHPDoc की याद आती है जब refactoring)

नीचे देखें कोड:

class MyObj
{
    private $val;
    public function __construct($val) { $this->val = $val; }
    public function getter() { return $this->val; }
}

/**
 * @method MyObj current()
 */
class MyObjCollection extends ArrayIterator
{
    public function __construct(Array $array = [])
    {
        foreach($array as $object)
        {
            if(!is_a($object, MyObj::class))
            {
                throw new Exception('Invalid object passed to ' . __METHOD__ . ', expected type ' . MyObj::class);
            }
        }
        parent::__construct($array);
    }

    public function echoContents()
    {
        foreach($this as $key => $myObj)
        {
            echo $key . ': ' . $myObj->getter() . '<br>';
        }
    }
}

$myObjCollection = new MyObjCollection([
    new MyObj(1),
    new MyObj('foo'),
    new MyObj('blah'),
    new MyObj(23),
    new MyObj(array())
]);

$myObjCollection->echoContents();

यहाँ की कुंजी @method MyObj current()PHPDoc है जो ArrayIterator (जो है mixed) से विरासत में मिली रिटर्न प्रकार को ओवरराइड करती है । इस PHPDoc को शामिल करने का मतलब है कि जब हम उपयोग करने वाले वर्ग के गुणों पर पुनरावृति करते हैं foreach($this as $myObj), तो हम चर को संदर्भित करते हुए कोड को पूरा करते हैं।$myObj->...

मेरे लिए, यह इसे प्राप्त करने का सबसे साफ तरीका है (कम से कम जब तक PHP टाइप किए गए एरर्स का परिचय नहीं देता है, यदि वे कभी भी करते हैं), जैसा कि हम पुनरावृत्त वर्ग में पुनरावृत्त प्रकार की घोषणा कर रहे हैं, न कि पूरे कोड में बिखरे हुए वर्ग के उदाहरणों पर।

मैंने यहाँ ArrayIterator का विस्तार करने के लिए पूर्ण समाधान नहीं दिखाया है, इसलिए यदि आप इस तकनीक का उपयोग करते हैं, तो आप यह भी कर सकते हैं:

  • आवश्यकतानुसार अन्य क्लास-स्तर के PHPDoc को शामिल करें, जैसे offsetGet($index)औरnext()
  • is_a($object, MyObj::class)कंस्ट्रक्टर से एक निजी पद्धति में पवित्रता की जाँच करें
  • इसे (अब निजी) पवित्रता की जाँच करें जैसे कि विधि ओवरराइड से offsetSet($index, $newval)औरappend($value)

बहुत अच्छा और साफ समाधान! :)
मार्को Janutija

2

समस्या यह है कि @varकेवल एक प्रकार को निरूपित कर सकते हैं - एक जटिल सूत्र शामिल नहीं है। यदि आपके पास "Foo की सरणी" के लिए एक सिंटैक्स था, तो वहां क्यों रुकें और "array of array" के लिए एक सिंटैक्स न जोड़ें, जिसमें 2 Foo और तीन बार का "" हो? मैं समझता हूं कि तत्वों की एक सूची शायद इससे अधिक सामान्य है, लेकिन यह एक फिसलन ढलान है।

व्यक्तिगत रूप से, मैंने कुछ समय @var Foo[]"फू की एक सरणी" को दर्शाने के लिए उपयोग किया है, लेकिन यह आईडीई द्वारा समर्थित नहीं है।


5
सी / सी ++ के बारे में मुझे जो चीजें पसंद हैं उनमें से एक यह है कि यह वास्तव में इस स्तर तक नीचे के प्रकारों का ट्रैक रखता है। यह नीचे फिसलने के लिए एक बहुत ही सुखद ढलान होगा।
ब्रिलियनड

2
Netbeans 7.2 (कम से कम वह संस्करण जिसका मैं उपयोग करता हूं) द्वारा समर्थित है, लेकिन थोड़े अन्याय के साथ अर्थात् /* @var $foo Foo[] */:। बस इसके बारे में नीचे एक जवाब लिखा है। यह भी foreach(){}छोरों के अंदर इस्तेमाल किया जा सकता है
Highmastdon

1
<?php foreach($this->models as /** @var Model_Object_WheelModel */ $model): ?>
    <?php
    // Type hinting now works:
    $model->getImage();
    ?>
<?php endforeach; ?>

5
कौन सी आईडीई इसका समर्थन करती है?
दार्शनिको

21
यह बहुत बदसूरत है। जब आप इस तरह की प्रोग्रामिंग शुरू करते हैं तो कोड को साफ करने के लिए अलविदा कहें।
अर्धपत्थर.साम

सरणी की सामग्री को परिभाषित करने के साथ मेरे जवाब को देखें: stackoverflow.com/a/14110784/431967
Highmastdon

-5

मुझे कुछ मिला है, जो काम कर रहा है, यह जान बचा सकता है!

private $userList = array();
$userList = User::fetchAll(); // now $userList is an array of User objects
foreach ($userList as $user) {
   $user instanceof User;
   echo $user->getName();
}

11
केवल समस्या यह है कि निष्पादित किए जाने वाले अतिरिक्त कोड का परिचय देता है, जिसका उपयोग केवल आपके आईडीई द्वारा किया जाता है। इसके बजाय टिप्पणियों के भीतर टाइप हिंटिंग को परिभाषित करना बेहतर है।
बेन रोवे

1
वाह यह महान काम करता है। आप अतिरिक्त कोड के साथ समाप्त होंगे लेकिन यह हानिरहित प्रतीत होता है। मैं करने जा रहा हूँ: $ x इंस्टोफ़ वाई; // टाइपहिंट
इगोर

3
एक आईडीई पर स्विच करें जो आपको डॉकब्लॉक या निरीक्षण के आधार पर कोड पूरा करने देता है। यदि आप अपनी IDE फ़ाइल को अपने IDE के समस्या ट्रैकर पर सुविधा अनुरोध को स्विच नहीं करना चाहते हैं।
डैनियलवेर्नी

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