我在自定义函数中尝试使用 PHP 的 mixed 类型,但这个错误让我很困惑(标点符号是我的):
TypeError: Argument 1 passed to <functionName>() must be an instance of
mixed,stringgiven.
下面的一些(示例)代码会导致错误消息并说明我希望实现的目标。下面是一些 TLDR 和进一步的解释。但基本上,我将 mixed 视为某些 PHP 原生函数(例如 is_string 函数)的参数类型,并希望在自定义函数中执行相同的操作。
如何显式指定函数参数是多类型/混合/任意?
<?php
function echoMixed(mixed $input) {
if (!is_array($input)) {
echo mixed;
} else {
// For arrays echo each element using recursive call.
foreach($input as $current) {
echoMixed($current);
}
}
}
echoMixed('test'); // <-- This results in the error.
echoMixed(['test1', 'test2']);
?>
我是 PHP 的新手,但正在尝试“新的”显式类型系统。我使用的是 PHP 7.x,但我认为这是在 PHP 5.0 中引入的。我喜欢 TypeScript 语言的可选类型系统,最初假设 mixed 的工作方式与类型 any 相同。在 typescript 中。 PHP documentation on mixed只是加强了这个假设,因为它指出:
mixed indicates that a parameter may accept multiple (but not necessarily all) types.
但在收到此错误后,似乎 mixed 是完全不同的东西。这是针对具有混合类型或其他值的数组吗?
最佳答案
要实现您想要的效果,您只需省略 mixed 并且不指定类型提示。 PHP NOT 没有语言关键字来明确指定参数可以是不同的类型。
请注意,mixed 在文档中被命名为关键字,但它不是“语言关键字”,而是仅在 PHPDocs 中的关键字。 array|object、number、void 和其他伪类型也是如此。您可以在代码中使用的实际类型在 PHP 中被命名为 primitives,请参阅以下文档摘录。
以下是允许的类型和使用它们的最低 PHP 版本:
Class/interface name - PHP 5.0.0
self - PHP 5.0.0
array - PHP 5.1.0
callable - PHP 5.4.0
bool - PHP 7.0.0
float - PHP 7.0.0
int - PHP 7.0.0
string - PHP 7.0.0
mixed - PHP 8.0.0
static - PHP 8.0.0 (for return type only)
PHP 8.0 还引入了具有以下语法的联合类型:bool|string 这将允许 bool 值或字符串。 ( rfc )
警告:integer 和boolean 不能用作类型提示
来源:http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration
PHP 原始类型
string A piece of text of an unspecified length.
int or integer A whole number that may be either positive or negative.
float A real, or decimal, number that may be either positive or negative.
bool or boolean A variable that can only contain the state ‘true’ or ‘false’.
array A collection of variables of unknown type. It is possible to specify the types of array members, see the chapter on arrays for more information.
resource A file handler or other system resource as described in the PHP manual.
null The value contained, or returned, is literally null. This type is not to be confused with void, which is the total absence of a variable or value (usually used with the @return tag).
callable A function or method that can be passed by a variable, see the PHP manual for more information on callables.
关键字(非 PHP 原生)
mixed A value with this type can be literally anything; the author of the documentation is unable to predict which type it will be.
void This is not the value that you are looking for. The tag associated with this type does not intentionally return anything. Anything returned by the associated element is incidental and not to be relied on.
object An object of any class is returned,
false or true An explicit boolean value is returned; usually used when a method returns ‘false’ or something of consequence.
self An object of the class where this type was used, if inherited it will still represent the class where it was originally defined.
static An object of the class where this value was consumed, if inherited it will represent the child class. (see late static binding in the PHP manual).
$this This exact object instance, usually used to denote a fluent interface.
来源: https://www.phpdoc.org/docs/latest/guides/types.html#primitives
2021 年更新
关于PHP 混合类型 vs Typescript any,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41267772/
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
我有一个模块:moduleMyModuledefdo_something#...endend由类使用如下:classMyCommandextendMyModuledefself.execute#...do_somethingendend如何验证MyCommand.execute调用了do_something?我已经尝试使用mocha进行部分模拟,但是当未调用do_something时它不会失败:it"callsdo_something"doMyCommand.stubs(:do_something)MyCommand.executeend 最佳答案
所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass
我想使用PostgreSQL中的point类型。我已经完成了:railsgmodelTestpoint:point最终的迁移是:classCreateTests当我运行时:rakedb:migrate结果是:==CreateTests:migrating====================================================--create_table(:tests)rakeaborted!Anerrorhasoccurred,thisandalllatermigrationscanceled:undefinedmethod`point'for#/hom
希望我没有误解“ducktyping”的含义,但从我读到的内容来看,这意味着我应该根据对象如何响应方法而不是它是什么类型/类来编写代码。代码如下:defconvert_hash(hash)ifhash.keys.all?{|k|k.is_a?(Integer)}returnhashelsifhash.keys.all?{|k|k.is_a?(Property)}new_hash={}hash.each_pair{|k,v|new_hash[k.id]=v}returnnew_hashelseraise"CustomattributekeysshouldbeID'sorPropertyo