PHP类型暗示原语值?
我想知道是否可以使用类型提示方法来期望基元类型 大概是这样的:PHP类型暗示原语值?,php,primitive-types,type-hinting,Php,Primitive Types,Type Hinting,我想知道是否可以使用类型提示方法来期望基元类型 大概是这样的: public function someMethod(string $str) //^^^^^^ 或: 同样的方式,你会: private function otherMethod(Person $rambo) //^^^^^^ 这在php中可能吗?在php 7中,他们添加了以下内容: 类型声明允许函数在调用时要求参数为特定类
public function someMethod(string $str)
//^^^^^^
或:
同样的方式,你会:
private function otherMethod(Person $rambo)
//^^^^^^
这在php中可能吗?在php 7中,他们添加了以下内容: 类型声明允许函数在调用时要求参数为特定类型。如果给定值的类型不正确,则会生成一个错误:在PHP5中,这将是一个可恢复的致命错误,而PHP7将抛出一个TypeError异常 参考:
当问到这个问题时,PHP 5是最新的,并说: PHP5引入了类型暗示。函数现在可以强制参数成为对象(通过在函数原型中指定类的名称)、接口、数组(自PHP 5.1起)或可调用(自PHP 5.4起)。但是,如果将NULL用作默认参数值,则允许它作为以后任何调用的参数 若类或接口被指定为类型提示,那个么它的所有子类或实现也是允许的 类型提示不能与int或string等标量类型一起使用。也不允许使用资源和特征
参考资料:否。您不能为原语键入提示,因为PHP具有原语的自动转换。看见这永远不会改变,除非PHP团队突然改变主意(这是值得怀疑的,他们相当顽固)。基本类型不支持类型暗示 不过,类和接口都支持它
编辑:我忘了提到数组也支持这种功能。我想你不需要PHP的类型提示,因为你有类型检查函数,比如is_bool()、is_string()等等,所以你可以在把它变成一个参数之前,检查你试图放入参数中的任何东西,虽然他们用来检查数组和对象类型的方法会更干净。每个人都已经说过了,但是你不能对原语进行类型提示,因为PHP不支持它。这背后的原因不仅与自动转换有关,也与社区反应有关 到目前为止,我还记得在2010年5月,PHP主干中添加了对标量类型暗示的支持。但由于社区的反应,这一功能没有进入5.4版本 对此有点争议。反对这一改变的人认为,这种支持将违背PHP的基本设计。PHP被认为是一种弱类型语言。本质上,这意味着PHP不需要您声明数据类型。变量仍然有与之关联的数据类型,但您可以做一些根本性的事情,例如向整数添加字符串而不会导致错误 IMHO:标量类型暗示应该尽快添加到PHP中,这是我们都需要的功能,我真的很尊重PHP是弱类型语言,但对于高端开发和生产,特别是在OO上下文中,标量类型暗示是必须具备的。在PHP中,我们可以有两种选择,就像过程和OO一样。是的,现在这是可能的, 经过长时间的讨论,一项针对标量函数参数和返回值实现类型暗示的建议刚刚获得批准,投票数达到了目前为止的最高水平,请查看详细信息: 标量类型暗示包括声明函数参数类型和返回值,返回值可以是int、float、string和bool类型。这允许PHP运行时引擎检查传递给参数函数和返回值的值类型是否为预期类型,以便检测最终的编程错误。 在过去的PHP版本中,已经允许对对象、数组和可调用项进行类型暗示。 当前的实现引入了五个新的保留字:int、float、bool、string和numeric。这些之前没有保留,因为铸造是lexer中的一个特例
Example :
function test(float $a) {
var_dump($a);
}
test(1); // float(1)
test("1"); // float(1)
test(1.0); // float(1)
test("1a"); // E_RECOVERABLE_ERROR
test("a"); // E_RECOVERABLE_ERROR
test(""); // E_RECOVERABLE_ERROR
test(1.5); // float(1.5)
test(array()); // E_RECOVERABLE_ERROR
test(new StdClass); // E_RECOVERABLE_ERROR
您还可以选择在源文件中声明,允许Scaler类型暗示。它必须是配置脚本的第1行,不能在同一文件的其他位置声明
Like : declare(strict_types=1);
在运行时,当PHP引擎尝试返回一个值时,它将检查是否与声明的不匹配,并抛出如下致命错误:,
致命错误:传递给increment()的参数1必须是给定字符串的整型
有了这个声明的新特性,您可以通过检测将错误类型的值传递给函数而导致的早期编程错误来编写更健壮的应用程序
也可能发生类型的自动更改。例如,int类型可以自动更改为float类型参数
function test(float $x){
var_dump($x);
}
test(10); // works fine
声明返回类型
我们可以在函数声明的最后一个括号和第一个括号之间添加一个冒号,后跟期望的类型来声明返回类型
对于不返回任何值的函数,不应在返回类型声明部分添加任何内容
function mustReturnInt(): int { ... }
function mustReturnString(): string { ... }
function mustReturnBool(): bool { ... }
function mustReturnFloat(): float { ... }
function doesNotReturnAnything() { ... }
一个更复杂的例子
declare(strict_types=1);
class StrictTypesTestingClass {
public function returnSameInt(int $value): int { return $value; }
public function returnSameFloat(float $value): float { return $value; }
public function returnSameString(string $value): string { return $value; }
public function returnSameBool(bool $value): bool { return $value; } }
$check = new StrictTypesTestingClass(); // calls that work print $check->returnSameInt(10);
print $check->returnSameFloat(10.0);
print $check->returnSameString("test");
print $check->returnSameBool(true) ? 'true' : 'false'; // calls that throw exceptions
print $check->returnSameInt("10");
print $check->returnSameFloat("10.0");
print $check->returnSameString(10);
print $check->returnSameBool("true");
弱类型检查和类型转换的行为:弱类型检查模式可与语句declare一起使用(strict_types=0);或者缺少严格的类型声明。有几点需要考虑:
对扩展或内置PHP函数的弱类型检查调用与以前的PHP版本中的行为相同
新标量类型声明的弱类型检查规则与扩展或内置PHP函数的弱类型检查规则基本相同。
NULL是一种特殊情况,以便与类、可调用项和数组的当前类型声明保持一致。默认情况下不接受NULL,除非它是一个参数,并且显式地指定了默认值NULL,例如:function sample(int$a=NULL)
这种方法有很多优点。你得到类型安全。这意味着您最终可以静态分析代码!你可以
declare(strict_types=1);
class StrictTypesTestingClass {
public function returnSameInt(int $value): int { return $value; }
public function returnSameFloat(float $value): float { return $value; }
public function returnSameString(string $value): string { return $value; }
public function returnSameBool(bool $value): bool { return $value; } }
$check = new StrictTypesTestingClass(); // calls that work print $check->returnSameInt(10);
print $check->returnSameFloat(10.0);
print $check->returnSameString("test");
print $check->returnSameBool(true) ? 'true' : 'false'; // calls that throw exceptions
print $check->returnSameInt("10");
print $check->returnSameFloat("10.0");
print $check->returnSameString(10);
print $check->returnSameBool("true");
function set_active ( $state ) {
$this->is_active = true === $state;
}
<?php
define('TYPEHINT_PCRE', '/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/');
class Typehint
{
private static $Typehints = array(
'boolean' => 'is_bool',
'integer' => 'is_int',
'float' => 'is_float',
'string' => 'is_string',
'resource' => 'is_resource'
);
private function __Constrct() {}
public static function initializeHandler()
{
set_error_handler('Typehint::handleTypehint');
return TRUE;
}
private static function getTypehintedArgument($ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue)
{
foreach ($ThBackTrace as $ThTrace)
{
// Match the function; Note we could do more defensive error checking.
if (isset($ThTrace['function']) && $ThTrace['function'] == $ThFunction)
{
$ThArgValue = $ThTrace['args'][$ThArgIndex - 1];
return TRUE;
}
}
return FALSE;
}
public static function handleTypehint($ErrLevel, $ErrMessage)
{
if ($ErrLevel == E_RECOVERABLE_ERROR)
{
if (preg_match(TYPEHINT_PCRE, $ErrMessage, $ErrMatches))
{
list($ErrMatch, $ThArgIndex, $ThClass, $ThFunction, $ThHint, $ThType) = $ErrMatches;
if (isset(self::$Typehints[$ThHint]))
{
$ThBacktrace = debug_backtrace();
$ThArgValue = NULL;
if (self::getTypehintedArgument($ThBacktrace, $ThFunction, $ThArgIndex, $ThArgValue))
{
if (call_user_func(self::$Typehints[$ThHint], $ThArgValue))
{
return TRUE;
}
}
}
}
}
return FALSE;
}
}
Typehint::initializeHandler();
?>
An are some examples of the class in use:
<?php
function teststring(string $string) { echo $string; }
function testinteger(integer $integer) { echo $integer; }
function testfloat(float $float) { echo $float; }
// This will work for class methods as well.
?>