क्या PHP की जेनेरिक की कमी के आसपास कोई भी सभ्य काम है जो स्थैतिक कोड निरीक्षण को प्रकार की स्थिरता का पता लगाने की अनुमति देता है?
मेरे पास एक अमूर्त वर्ग है, जिसे मैं उप-वर्ग करना चाहता हूं और यह भी लागू करता हूं कि किसी एक प्रकार के पैरामीटर को लेने से, एक पैरामीटर को लेने के लिए जो कि उस पैरामीटर का एक उप-वर्ग है, उनमें से एक विधि बदल जाती है।
abstract class AbstractProcessor {
abstract function processItem(Item $item);
}
class WoodProcessor extends AbstractProcessor {
function processItem(WoodItem $item){}
}
यह PHP में अनुमति नहीं है क्योंकि यह उन तरीकों के हस्ताक्षर को बदल रहा है जिन्हें अनुमति नहीं है। जावा स्टाइल जेनेरिक से आप कुछ ऐसा कर सकते हैं:
abstract class AbstractProcessor<T> {
abstract function processItem(T $item);
}
class WoodProcessor extends AbstractProcessor<WoodItem> {
function processItem(WoodItem $item);
}
लेकिन जाहिर है PHP उन लोगों का समर्थन नहीं करता है।
इस समस्या के लिए, लोग सुझाव देते instanceof
हैं कि रन-टाइम पर त्रुटियों की जाँच करें
class WoodProcessor extends AbstractProcessor {
function processItem(Item $item){
if (!($item instanceof WoodItem)) {
throw new \InvalidArgumentException(
"item of class ".get_class($item)." is not a WoodItem");
}
}
}
लेकिन यह केवल रनटाइम पर काम करता है, यह आपको स्थैतिक विश्लेषण का उपयोग करके त्रुटियों के लिए अपने कोड का निरीक्षण करने की अनुमति नहीं देता है - तो क्या PHP में इसे संभालने का कोई समझदार तरीका है?
समस्या का एक और पूर्ण उदाहरण है:
class StoneItem extends Item{}
class WoodItem extends Item{}
class WoodProcessedItem extends ProcessedItem {
function __construct(WoodItem $woodItem){}
}
class StoneProcessedItem extends ProcessedItem{
function __construct(StoneItem $stoneItem){}
}
abstract class AbstractProcessor {
abstract function processItem(Item $item);
function processAndBoxItem(Box $box, Item $item) {
$processedItem = $this->processItem($item);
$box->insertItem($item);
}
//Lots of other functions that can call processItem
}
class WoodProcessor extends AbstractProcessor {
function processItem(Item $item) {
return new ProcessedWoodItem($item); //This has an inspection error
}
}
class StoneProcessor extends AbstractProcessor {
function processItem(Item $item) {
return new ProcessedStoneItem($item);//This has an inspection error
}
}
क्योंकि मैं सिर्फ एक में गुजर रहा हूँ Item
करने के लिए new ProcessedWoodItem($item)
और यह पैरामीटर के रूप में एक WoodItem उम्मीद कोड निरीक्षण से पता चलता है कि कोई त्रुटि है।