Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP类型转换-好还是坏?_Php_Types - Fatal编程技术网

PHP类型转换-好还是坏?

PHP类型转换-好还是坏?,php,types,Php,Types,在用C和Java做了一些工作之后,我越来越被PHP中狂野的西方法则所困扰。我真正觉得PHP缺少的是严格的数据类型。字符串('0')==(int)0==(boolean)false就是一个例子 不能依赖函数返回的数据类型。您既不能强制函数的参数为特定类型,这可能会导致非严格比较,从而导致意外情况。一切都可以搞定,但仍然会出现意想不到的bug 对方法接收的参数进行类型转换是好的还是坏的做法?打印报税表好吗 即 这个例子很愚蠢,我还没有测试过,但我认为每个人都明白这个想法。除了让不知道数据类型的人使用

在用C和Java做了一些工作之后,我越来越被PHP中狂野的西方法则所困扰。我真正觉得PHP缺少的是严格的数据类型。字符串('0')==(int)0==(boolean)false就是一个例子

不能依赖函数返回的数据类型。您既不能强制函数的参数为特定类型,这可能会导致非严格比较,从而导致意外情况。一切都可以搞定,但仍然会出现意想不到的bug

对方法接收的参数进行类型转换是好的还是坏的做法?打印报税表好吗


这个例子很愚蠢,我还没有测试过,但我认为每个人都明白这个想法。除了让不知道数据类型的人使用PHP之外,PHP之神还有什么理由可以随心所欲地转换数据类型吗?

不,类型转换不好,因为你不知道最终会得到什么。我个人建议使用函数,如
intval()
floatval()
,等等。

可以用于复杂类型。如果需要比较值+类型,可以使用“”进行比较

(0 === false) => results in false
(0 == false) => results in true

还可以编写
返回(数组)$result这毫无意义。在本例中,如果希望返回类型为数组,您需要的是
返回数组($result)

我认为这并不坏,但我会更进一步:用于复杂类型,如果简单类型不是您期望的类型,则抛出异常。通过这种方式,您可以让客户了解强制转换的任何成本/问题(例如从int->float或float->int的精度损失)

不过,上面代码中对数组的强制转换有误导性——您应该创建一个包含一个值的新数组

综上所述,您的上述示例变成:

public function doo($foo, $bar) {
   if (!is_int($foo)) throw new InvalidArgumentException();
   if (!is_float($bar)) throw new InvalidArgumentException();
   $result = $bar + $foo;
   return array($result);
}
PHP的下一个版本(可能是5.4)


但除此之外:动态类型转换并不是你应该讨厌和避免的事情。大多数情况下,它将按预期工作。如果没有,则通过检查
是否为某种类型来修复它,通过使用严格比较,…

无论好坏,松散键入都是“PHP方式”。许多内置程序和大多数语言结构都将对您提供的任何类型进行操作——在幕后无声地(通常是危险地)将它们转换为各种类型,以使事情(某种程度上)结合在一起

我本人来自Java/C/C++背景,PHP松散的类型模型一直让我感到沮丧。但是多年来我发现,如果我必须编写PHP,我可以通过接受PHP的“松散性”,而不是与之抗争,更好地完成它(即更干净、更安全、更可测试的代码);因此我成了一只快乐的猴子

强制转换确实是我的技术的基础——而且(IMHO)它是一致构建干净、可读的PHP代码的唯一方法,该代码以一种易于理解、可测试、确定性的方式处理混合类型参数

要点(您也清楚地理解)是,在PHP中,您不能简单地假设参数是您期望的类型。这样做可能会产生严重后果,直到你的应用程序投入生产后,你才可能受到影响

为了说明这一点:

<?php

function displayRoomCount( $numBoys, $numGirls ) {
  // we'll assume both args are int

  // check boundary conditions
  if( ($numBoys < 0) || ($numGirls < 0) ) throw new Exception('argument out of range');

  // perform the specified logic
  $total = $numBoys + $numGirls;
  print( "{$total} people: {$numBoys} boys, and {$numGirls} girls \n" );
}

displayRoomCount(0, 0);   // (ok) prints: "0 people: 0 boys, and 0 girls" 

displayRoomCount(-10, 20);  // (ok) throws an exception

displayRoomCount("asdf", 10);  // (wrong!) prints: "10 people: asdf boys, and 10 girls"
尽管
$db_row['boys']
$db_row['girls']
实际上是包含数值的字符串,但这两个字符串都可以正常工作。这与PHP开发者(不知道C、C++或java)的预期方式一致。
至于强制转换返回值:这样做没有什么意义,除非您知道您有一个潜在的混合类型变量,并且希望始终确保返回值是特定类型。在代码的中间点,而不是从函数返回时,更经常出现这种情况

一个实际例子:

<?php

function getParam( $name, $idx=0 ) {
  $name = (string)$name;
  $idx = (int)$idx;

  if($name==='') return null;
  if($idx<0) $idx=0;

  // $_REQUEST[$name] could be null, or string, or array
  // this depends on the web request that came in.  Our use of
  // the array cast here, lets us write generic logic to deal with them all
  //
  $param = (array)$_REQUEST[$name];

  if( count($param) <= $idx) return null;
  return $param[$idx];
}

// here, the cast is used to ensure that we always get a string
// even if "fullName" was missing from the request, the cast will convert
// the returned NULL value into an empty string.
$full_name = (string)getParam("fullName");

怎么会这样?要么强制转换将成功,您将获得正确的类型值,要么执行将失败(将抛出异常,或者PHP将爆炸,具体取决于PHP版本)。这里有什么我遗漏的吗?我也很好奇比利说的话。intval()的作用与使用(int)进行类型转换相同,我知道示例中存在缺陷。这是我用C语言做的方式,但正如你所说,我绝对不会用PHP做。这主要是因为示例中的一致性。我知道类型暗示,但它不适用于基本类型:(它只会在标题中查找类“int”,我不确定是否同意(同样,在php.internals上,只需要两个人私下交谈就可以安排发布)。虽然有一个补丁,但我不确定是否同意在PHP.Err中使用。PHP已经支持类型暗示(并且已经有一段时间了)@Billy:它不支持标量类型提示,这就是我们在这里讨论的。我们是否也可以看到方法返回的类型提示,或者它们只会起到一半作用?目前只支持函数参数的类型提示。虽然函数返回值类型提示已经有RFC存在多年了。也许他们会得到它;)我认为这是我思想上的一大进步。有什么开销需要考虑吗?是的,在PHP中调用函数很慢。但由于过早优化是万恶之源,所以不要考虑这些微小的、不重要的减速,而要考虑代码的可读性和可维护性;)@安德斯:是的,有间接费用,但我认为这并不重要。PHP必须检查类型,以便在任何情况下执行强制转换。当然,这张支票不是免费的。我想我会试试这个办法。不管怎样,数据库查询和传输这些结果总是在我发现我站点上的显著瓶颈时,您可能会认为弱类型(例如PHP、JavaScript、SimalTalk、C、C++等)是一个缺陷,但它是PHP的设计的一部分,因此是U的设计。
<?php

function displayRoomCount( $numBoys, $numGirls ) {
  // we cast to ensure that we have the types we expect
  $numBoys = (int)$numBoys;
  $numGirls = (int)$numGirls;

  // check boundary conditions
  if( ($numBoys < 0) || ($numGirls < 0) ) throw new Exception('argument out of range');

  // perform the specified logic
  $total = $numBoys + $numGirls;
  print( "{$total} people: {$numBoys} boys, and {$numGirls} girls \n" );
}

displayRoomCount("asdf", 10);  // (ok now!) prints: "10 people: 0 boys, and 10 girls"
// assume $db_row read from a database of some sort
displayRoomCount( $db_row['boys'], $db_row['girls'] ); 
<?php

function getParam( $name, $idx=0 ) {
  $name = (string)$name;
  $idx = (int)$idx;

  if($name==='') return null;
  if($idx<0) $idx=0;

  // $_REQUEST[$name] could be null, or string, or array
  // this depends on the web request that came in.  Our use of
  // the array cast here, lets us write generic logic to deal with them all
  //
  $param = (array)$_REQUEST[$name];

  if( count($param) <= $idx) return null;
  return $param[$idx];
}

// here, the cast is used to ensure that we always get a string
// even if "fullName" was missing from the request, the cast will convert
// the returned NULL value into an empty string.
$full_name = (string)getParam("fullName");