PHP में सख्त प्रकार क्या करते हैं?


147

मैंने PHP 7 में निम्नलिखित नई लाइन देखी है, लेकिन कोई भी वास्तव में इसका मतलब नहीं बताता है। मैंने इसे देखा है और वे सभी के बारे में बात करते हैं कि क्या आप इसे किसी प्रकार की चीज की तरह सक्षम कर रहे हैं या नहीं।

declare(strict_types = 1);

यह क्या करता है? यह मेरे कोड को कैसे प्रभावित करता है? क्या मुझे यह करना चाहिए?

कुछ स्पष्टीकरण अच्छा होगा।



5
इस पर भी एक नज़र डालिए। php.net/manual/en/… के लिए सख्त_टाइप निर्देश
scaisEdge

जवाबों:


153

से ट्रीहाउस ब्लॉग :

PHP 7 के साथ हमने अब स्केलर प्रकार जोड़े हैं। विशेष रूप से: इंट, फ्लोट, स्ट्रिंग और बूल।

स्केलर प्रकार के संकेत जोड़ने और सख्त आवश्यकताओं को सक्षम करने से, यह आशा की जाती है कि अधिक सही और स्व-दस्तावेजीकरण PHP प्रोग्राम लिखे जा सकते हैं। यह आपको अपने कोड पर अधिक नियंत्रण भी देता है और कोड को पढ़ना आसान बना सकता है।

डिफ़ॉल्ट रूप से, स्केलर प्रकार-घोषणाएं गैर-सख्त हैं, जिसका अर्थ है कि वे मूल प्रकार को बदलने के लिए प्रकार-घोषणा द्वारा निर्दिष्ट प्रकार से मिलान करने का प्रयास करेंगे। दूसरे शब्दों में, यदि आप एक स्ट्रिंग को पास करते हैं जो एक फ़ंक्शन में संख्या के साथ शुरू होती है जिसे फ्लोट की आवश्यकता होती है, तो यह शुरुआत से संख्या को पकड़ लेगा और बाकी सब कुछ हटा देगा। एक फ्लोट को एक फ़ंक्शन में पास करना जिसमें एक इंट की आवश्यकता होती है वह इंट (1) बन जाएगा।

यदि संभव हो तो डिफ़ॉल्ट रूप से, PHP गलत प्रकार के मानों को अपेक्षित स्केलर प्रकार में डालेगा। उदाहरण के लिए, एक फ़ंक्शन जिसे एक स्ट्रिंग की अपेक्षा एक पैरामीटर के लिए पूर्णांक दिया जाता है, उसे टाइप स्ट्रिंग का एक चर मिलेगा।

सख्त प्रकार अक्षम ( निष्कासित ):

<?php

  function AddIntAndFloat(int $a, float $b) : int
  {
      return $a + $b;
  }

  echo AddIntAndFloat(1.4, '2');
  /*
  * without strict typing, PHP will change float(1.4) to int(1)
  * and string('2') to float(2.0) and returns int(3)
  */

प्रति फ़ाइल के आधार पर सख्त मोड को सक्षम करना संभव है। सख्त मोड में, केवल सटीक प्रकार की घोषणा के एक चर को स्वीकार किया जाएगा, या एक टाइपर फेंका जाएगा। इस नियम का एकमात्र अपवाद यह है कि एक पूर्णांक एक फ़ंक्शन को दिया जा सकता है जो फ्लोट की अपेक्षा करता है। आंतरिक कार्यों के भीतर से फ़ंक्शन कॉल सख्त_टाइप्स घोषणा से प्रभावित नहीं होंगे।

सख्त मोड को सक्षम करने के लिए, डिक्लेयर स्टेटमेंट का उपयोग सख्त_टाइप्स घोषणा के साथ किया जाता है:

सख्त प्रकार (सक्षम eval ):

<?php declare(strict_types=1);

  function AddIntAndFloat(int $a, float $b): int
  {
      return (string) $a + $b;
  }

  echo AddIntAndFloat(1.4,'2');
  // Fatal error: Uncaught TypeError: Argument 1 passed to AddIntAndFloat() must be of the type int, float given
  echo AddIntAndFloat(1,'2');
  // Fatal error: Uncaught TypeError: Argument 2 passed to AddIntAndFloat() must be of the type float, string given

  // Integers can be passed as float-points :
  echo AddIntAndFloat(1,1);
  // Fatal error: Uncaught TypeError: Return value of AddIntAndFloat() must be of the type integer, string returned

काम करने का उदाहरण:

<?php

declare(strict_types=1);

function AddFloats(float $a, float $b) : float
{
    return $a+$b;
}

$float = AddFloats(1.5,2.0); // Returns 3.5

function AddFloatsReturnInt(float $a, float $b) : int
{
    return (int) $a+$b;
}

$int = AddFloatsReturnInt($float,1.5); // Returns 5

function Say(string $message): void // As in PHP 7.2
{
    echo $message;
}

Say('Hello, World!'); // Prints "Hello, World!"

function ArrayToStdClass(array $array): stdClass
{
    return (object) $array;
}

$object = ArrayToStdClass(['name' => 'azjezz','age' => 100]); // returns an stdClass

function StdClassToArray(stdClass $object): array
{
    return (array) $object;
}

$array = StdClassToArray($object); // Returns array

function ArrayToObject(array $array): object // As of PHP 7.2
{
    return new ArrayObject($array);
}

function ObjectToArray(ArrayObject $object): array
{
    return $object->getArrayCopy();
}

var_dump( ObjectToArray( ArrayToObject( [1 => 'a' ] ) ) ); // array(1 => 'a');

3
आपके सख्त प्रकार सक्षम उदाहरण में उल्लिखित पहली घातक त्रुटि गलत है। जैसा कि प्रलेखन में उल्लेख किया गया है: "इस नियम का एकमात्र अपवाद यह है कि एक पूर्णांक एक फ़ंक्शन को दिया जा सकता है जो फ्लोट की अपेक्षा कर रहा है।" फ़ंक्शन कॉल int पर विफल नहीं होगा। यह हालांकि स्ट्रिंग पर होगा।
पॉल

63

strict_types प्रकार के ज़बरदस्ती को प्रभावित करता है।

बिना प्रकार के संकेत का उपयोग strict_typesकरने से सूक्ष्म कीड़े हो सकते हैं।

सख्त प्रकारों से पहले, का int $xअर्थ है " एक int के लिए $xएक मान coercible होना चाहिए ।" कोई भी मान जो किसी के लिए ज़ब्त किया जा सकता है int, वह टाइप हिंट पास करेगा, जिसमें शामिल हैं:

  • a int उचित ( 242),
  • एक फ्लोट ( 10.17),
  • एक बूल ( true),
  • null, या
  • अग्रणी अंकों ( "13 Ghosts") के साथ एक स्ट्रिंग ।

सेटिंग करके strict_types=1, आप इंजन को बताते हैं int $xजिसका अर्थ है "$ x को केवल एक इंट उचित होना चाहिए, किसी भी प्रकार की जबरदस्ती की अनुमति नहीं है।" आपके पास बहुत अच्छा आश्वासन है कि आप बिना किसी रूपांतरण और संभावित हानि के, वास्तव में केवल और केवल वही प्राप्त कर रहे हैं।

उदाहरण:

<?php
function get_quantity(): int {
    return '100 apples';
}
echo get_quantity() . PHP_EOL;

एक संभावित भ्रामक परिणाम देता है:

Notice: A non well formed numeric value encountered in /Users/bishop/tmp/pmkr-994/junk.php on line 4
100

अधिकांश डेवलपर्स उम्मीद करेंगे, मुझे लगता है, int"केवल एक इंट" का मतलब है। लेकिन यह नहीं है, इसका मतलब है "एक int की तरह कुछ भी"। सख्त_टाइप को सक्षम करने से संभावित अपेक्षित और वांछित व्यवहार मिलता है:

<?php declare(strict_types=1);

function get_quantity(): int {
    return '100 apples';
}
echo get_quantity() . PHP_EOL;

पैदावार:

Fatal error: Uncaught TypeError: Return value of get_quantity() must be of the type int, string returned in example.php:4

मुझे लगता है कि यहां दो पाठ हैं, यदि आप टाइप संकेत का उपयोग करते हैं:

  • strict_types=1हमेशा उपयोग करें ।
  • अपवादों को नोटिफ़िकेशन करें, यदि आप strict_typesप्राग्म को जोड़ना भूल जाते हैं ।

1
यह पहले से ही लगभग एक साल पहले की तरह अच्छी तरह से उत्तर दिया गया है;)
एमिक्स

6
दरअसल, मैंने दूसरे उत्तर @emix को वोट दिया। हालांकि, मुझे लगा कि "मुझे यह करना चाहिए" का सवाल छुआ नहीं गया था। मैंने यह भी महसूस किया कि एक अधिक कॉम्पैक्ट और चौंकाने वाला उदाहरण लोगों को उपयोग करने के लिए प्रोत्साहित करेगा strict_types
बिशप

1
मुझे लगता है कि यह प्रश्न "मुझे ऐसा करना चाहिए?" ओपी के सवाल का हिस्सा। कुछ अंतराल के बाद PHP में लौटना और यह बहुत मददगार था।
दारागह सीधा 10
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.