2014-12-31 45 views
2

我想知道是否有可能限制php變量只接受它定義接受的某種類型的變量。我們可以限制PHP變量只接受某些類型的值

的e-g如果我們在C#中看到

public int variable = 20; 
public string variable2 = "Hello World"; 

所以會選擇什麼樣的PHP,如果我想限制變量類型。

public int $variable = 20; 

因此,如果我嘗試將字符串分配給整數變量,我會得到錯誤。

public int $varaible = "Hello World"; //As type is integer, it should throw error. 

是否有這樣的事情在PHP中爲變量賦值之前定義了類型?

+7

答案是簡單的「不」 .... PHP是一種鬆散類型的語言,這意味着你不能限制打字 –

+1

您可以在使用Hacklang只能做。 http://docs.hhvm.com/manual/en/hack.annotations.php – MisterBla

回答

7

TL; DR不是直接的,沒有。 PHP不是嚴格的類型。但是,有一些解決方法可以在函數參數或類的屬性的上下文中適用於您。

長答案: PHP不是嚴格類型的語言,而是鬆散類型的語言。無論初始化方式如何,您都可以爲變量賦予任何值。所以,你不能簡單地輸入類似int $myVar的東西,並期望$myVar = "foo";發生錯誤。但是PHP提供了一些方便的功能,可以在處理函數參數或類的屬性時達到相同的目的。

選項1:類型提示

可以使用"type hint"的功能參數:

class SomeClass 
{ 
    /* code here */ 
} 

function foo(SomeClass $data) 
{ 
    /* code here */ 
} 

foo()將只接受SomeClass類型的參數。通過它,例如,一個int將會引發致命錯誤。如果這些參數旨在爲基本類型,例如int,string等,則此功能在PHP <中不起作用,因此您無法執行function foo(int $data) {...}。也就是說,在那裏有幾個圖書館試圖以犧牲一點速度來強制它工作。另外,PHP 7爲這類事物增加了很多支持,就像基於PHP的Hack語言一樣。

優點:

  • 直觀

缺點:

  • 僅適用於程序定義的類
  • 不可用的基本類型

選項2:getter和setter

您還可以使用getter和setter方法,就像這樣:

class SomeClass 
{ 
    private $foo = 0; 

    function setFoo($val = 0) 
    { 
     // force it to be an int 
     if (is_integer($val) { 
      $this->foo = $val; 
     } else { 
      // throw an error, raise an exception, or otherwise respond 
     } 
    } 
} 

優點:

  • 相對容易
  • 相對直觀

缺點:

  • 只能在程序定義的類
  • 不可用的基本類型
  • 需要大量的代碼

方案3:魔術方法

這種方法是我最喜歡的,也是最複雜的。使用__set() magic method來處理類屬性。

class MyClass { 
    private $type = 0; // we will force this to be an int 
    private $string = ''; // we will force this to be a string 
    private $arr = array(); // we will force this to be an array 
    private $percent = 0; // we will force this to be a float in the range 0..100 

    function __set($name, $value) { 
     switch ($name) { 
      case "type": 
       $valid = is_integer($value); 
       break; 
      case "string": 
       $valid = is_string($value); 
       break; 
      case "arr": 
       $valid = is_array($value); 
       break; 
      case "percent": 
       $valid = is_float($value) && $value >= 0 && $value <= 100; 
       break; 
      default: 
       $valid = true; // allow all other attempts to set values (or make this false to deny them) 
     } 

     if ($valid) { 
      $this->{$name} = $value; 

      // just for demonstration 
      echo "pass: Set \$this->$name = "; 
      var_dump($value); 
     } else { 
      // throw an error, raise an exception, or otherwise respond 

      // just for demonstration 
      echo "FAIL: Cannot set \$this->$name = "; 
      var_dump($value); 
     } 
    } 
} 

$myObject = new MyClass(); 
$myObject->type = 1; // okay 
$myObject->type = "123"; // fail 
$myObject->string = 1; // fail 
$myObject->string = "123"; // okay 
$myObject->arr = 1; // fail 
$myObject->arr = "123"; // fail 
$myObject->arr = array("123"); // okay 
$myObject->percent = 25.6; // okay 
$myObject->percent = "123"; // fail 
$myObject->percent = array("123"); // fail 
$myObject->percent = 123456; // fail 

優點:

  • 比較容易
  • 直觀
  • 極其強大:一個二傳手統治他們所有

缺點:

  • 只能在程序定義的類
  • 不可用的基本類型
  • 需要大量switch ING或if/else邏輯
  • 可能導致的IDE沒有自動完成屬性正確類型
問題

這裏有一個demo of this approach

閉幕思考

最後,如果你使用像PHPStorm的IDE,不要忘了PHPDoc的類型提示:

/* @var integer */ 
$foo = 0; // will result in warnings if the IDE is configured properly and you try to do something like substr($foo, 1, 4); 

如果你真的想去硬核,您可以使用Hack進行強大的輸入,代價是使您的代碼不易移植,與主要IDE不兼容(現在)。

當然,這些都不是明確地驗證用戶輸入,並全面測試應用程序的意外的輸入響應類型的替代品。

+0

PHPStorm是PHP的__the__ IDE。感謝提到這一點。 +1。 –

+0

@AyeshK :)沒有參數;這是我發現唯一有用的一個。 –

4

編號PHP不是嚴格類型的語言。但是,您可以在函數和方法中使用type hints

如果類或接口被指定爲類型提示,那麼它的所有子代或實現也是允許的。

類型提示不能用於標量類型,如int或string。資源和特性也是不允許的。

的標量類型是:

  • string
  • bool
  • int
  • float

實例:

function (array $theArr) { 
    // body 
} 

class X { 
    public function __construct(SomeOtherClass $arg) { 
    // body 
    } 

    public function setFoo(Foo $foo) { 

    } 
} 

參見手冊更多的細節:http://php.net/manual/en/language.oop5.typehinting.php

+1

而對於int和字符串? – Debflav

+0

不是,不是'int','string''bool','float'。 – prodigitalson

+1

我知道,但也許它應該包含在你的答案;) – Debflav

0

你必須通過自己的雙手來做到了,例如:

function setInt(&$var, $value) { 
    if(!is_integer($value) { 
     throw new Exception("Integer wanted " . gettype($value) . " received"); 
    } 
    $var = $value; 
} 
相關問題