通过 PHP v5.3中的静态绑定,可以在接口中有效地声明静态方法;在PHP v5.4中具有特征,方法可以是静态还是抽象,但不能同时使用.这似乎是不合逻辑的和不一致的.

特别地,假设一个特征提供所有实现的接口,除了静态方法;除非该特性中声明了该方法,否则静态分析器将在特征内部引用任何引用.但是,在特征中提供具体的实现不再强制执行/使用类来提供自己的实现 – 这是危险的;抽象静态是理想的,但不允许.

这个矛盾的解释是什么?你会如何建议解决这个问题?

interface MyInterface
{
    public static function getSetting();
    public function doSomethingWithSetting();
}

trait MyTrait
{
    public abstract static function getSetting(); // I want this...

    public function doSomethingWithSetting() {
        $setting = static::getSetting(); // ...so that I can do this
        /* ... */
    }
}

class MyClass implements MyInterface
{
    use MyTrait;
    public static function getSetting() { return /* ... */ }
}
TL; DR:您可以在特征上定义抽象静态,但内部认为这是不好的做法,可能会在将来删除它.

没有多少咖啡因,但我会给它一个裂缝.

严格来说,抽象意味着子类必须实现,静态意味着这个特定类的代码.总而言之,抽象静态意味着“子类必须为此特定类实现代码”.完全正交的概念.

但是,PHP 5.3支持静态继承感谢LSB.所以我们实际上打开了这个定义:自己采用以前的静态定义,而static变为“这个特定类或其任何子类的代码”.抽象静态的新定义是“子类必须为此特定类或其任何子类实现代码”.这可能导致一些人在严格意义上认为静态混淆.参见例如bug #53081.

什么使特质如此特别的引出这个警告?那么看看实施通知的engine code:

if (ptr->flags & ZEND_ACC_STATIC && (!scope || !(scope->ce_flags & ZEND_ACC_INTERFACE))) {
    zend_error(error_type,"Static function %s%s%s() cannot be abstract",scope ? ZSTR_VAL(scope->name) : "",scope ? "::" : "",ptr->fname);
}

该代码表示​​允许抽象静态的唯一位置在接口内.特征不是唯一的,它是抽象静态的定义所独有的.为什么?那么我们的定义有一个小小的角落:

sub-class must implement code for this specific class or any of its sub-classes

使用此代码:

abstract class Foo {
    abstract public static function get();
}

那个定义意味着我应该能够调用Foo :: get.毕竟Foo是一个类(看到那个关键字“class”),而在严格的定义中,get就是要在这个类Foo中实现的.但是很明显,没有任何意义,因为我们回到了严格静态的正交性.

如果您尝试使用PHP,您可以获得唯一的理由响应:

Cannot call abstract method Foo::get()

所以因为PHP添加静态继承,它必须处理这些角落的情况.这是特征的本质.一些其他语言(C#,Java等)没有这个问题,因为它们采用严格的定义,根本不允许抽象静态.为了摆脱这种情况,简化引擎,我们可能会在将来强制执行这个“仅在接口中的抽象静态”规则.因此,E_STRICT.

我会使用服务代理来解决问题:

I have common method I want to use in several classes. This common method relies on a static method that must be defined externally to the common code.

trait MyTrait
{
    public function doSomethingWithSetting() {
        $service = new MyService($this);
        return $service->doSomethingWithSetting();
    }
}

class MyService
{
    public function __construct(MyInterface $object) {
        $this->object = $object;
    }
    public function doSomethingWithSetting() {
        $setting = $this->object->getSetting();
        return $setting;
    }
}

感觉有点Rube Goldberg.可能会看静态的动机,并考虑重构它们.

为什么PHP traits不具有静态抽象方法?的更多相关文章

  1. ios – NSURLProtocol的抽象方法

    我一直在我的应用程序中使用自定义NSURLProtocol来检测资源并从缓存目录加载(如果可用),或重定向回我的应用程序的服务器.但是,我发现缺少抽象方法的文档,我不知道如何处理我们需要实现的一些抽象方法.我们必须实施:canInitWithRequest很简单,这就是告诉NSURLProtocol您将响应此请求的方式.我不知道如何处理canonicalRequestForRequest:在sta

  2. 在Xcode 4中构建与Objective-c应用程序一起使用的静态C lib

    最好的祝福,吉米解决方法JimmyKoerting在评论中提供了正确的答案:应用程序需要与libstdc.dylib链接以解析标准库符号.感谢JimmyKoerting,但还有一件我想添加的内容是,如果您在iOS6.1中使用xcode最新版本,请添加此libstdc.6.dylib

  3. ios – 如何从故事板中创建的静态UITableView中删除单元格

    解决方法你不能真正处理这个数据源,因为使用静态表,你甚至没有实现数据源方法.高度是走的路.尝试这个:更新看来,在autolayout下,这可能不是最好的解决方案.有一个替代答案here可能有帮助.

  4. ios – 两个类,回调和单元测试

    而且,我不觉得这样的行为会很容易测试?

  5. ios – 在分组的表视图中混合静态和动态部分

    可能需要保持静电细胞的强大性能?在表视图的相同.xib文件中直接设计每个静态单元格,并为它们设置插座是否更好?(虽然这不允许重用我的自定义单元格设计…

  6. ios – OS X:将.dylib转换为.a / .o(动态到静态)?

    假设我已经阅读了thiscaveat,我仍然希望将TBB用作静态链接库.但我真的不想重写TBBmakefile来生成libtbb.a而不是libtbb.dylib.是否有一个简单的命令行方式将libtbb.dylib转换为libtbb.o并使用相同的入口点?

  7. xcode – Swift Constants文件 – 类还是结构?

    我想在我的Swift项目中创建一个Constants文件–填充静态let字符串.我应该创建一个结构还是一个类?

  8. ios – 如何将静态单元格拖入tableView swift?

    我在storyBoard中有一个tableView,我在其中添加了4个静态单元格,我的storyBoard看起来像:我没有这个tableView的任何dataSource,因为我的单元格是静态的.我使用下面的代码拖动一个单元格,它工作正常,直到我滚动一个表格.拖动后滚动它看起来像:正如你所看到的那样,细胞不再出现了.我想拖放静态单元格,我想保存它的位置,所以当我滚动时我不会再重新排列.Sample

  9. ios – 示例代码中AVFoundation.Framework中的静态void指针

    我正在浏览AVFoundation.Framework的示例代码–>AVSimpleEditoriOS&我发现以下一行我无法理解.考虑以下在上面的两行中,我可以看出那些是2个静态的void/generic指针,带有一些奇特的名字.现在回到这两行,我再次粘贴在这里,上面的意思是,2个静态void/generic指针存储它自己的&为什么它需要在什么意义上?我只需要很少的指导来学习这种编码模式.等待知识

  10. ios – Static Cells在Interface Builder中显示为空(运行XCode 7.1)

    解决方法终于找到了一个解决方法,因为这仍然发生在Xcode7.2Beta中:在InterfaceBuilder中,选择ViewController并在属性检查器中将其模拟大小设置为“Freeform”,然后切换到大小检查器并设置适合整个内容的高度.说实话,这比滚动更好.猜猜这将成为我在IB中静态表视图的默认设置.版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部