我正在转换PHP 5.3库以在PHP 5.2上工作.支持我的主要方法是使用后期静态绑定return new static($options);,如果我将其转换为return new self($options)将得到相同的结果?
new self和之间有什么区别new static?
我最近一直与提供商合作,我遇到了一个有趣的情况,我希望有一个抽象的静态方法.我读了一些关于这个主题的帖子,这有点意义,但有一个很清楚的解释吗?
我已经设置了一个抽象的父类,以及一个扩展它的具体类.为什么父类不能调用抽象函数?
//foo.php
<?php
abstract class AbstractFoo{
abstract public static function foo();
public static function getFoo(){
return self::foo();//line 5
}
}
class ConcreteFoo extends AbstractFoo{
public static function foo(){
return "bar";
}
}
echo ConcreteFoo::getFoo();
?>
Run Code Online (Sandbox Code Playgroud)
错误:
致命错误:无法 在第5行的foo.php中调用抽象方法AbstractFoo :: foo()
使用PHP v5.3中的后期静态绑定,可以static在接口中有用地声明方法; 对于PHP v5.4中的特征,方法可以是static或abstract但不是两者.这似乎是不合逻辑和不一致的.
特别地,假设一个具有特征提供所有实现的接口,静态方法除外; 除非在特征中声明了该方法,否则静态分析器会对特征内的任何引用进行跟踪.但是,在特征中提供具体实现不再强制实现/使用类来提供自己的实现 - 这是危险的; abstract static会是理想的,但不允许.
这个矛盾的解释是什么?你会如何建议解决这个问题?
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 /* ... */ }
}
Run Code Online (Sandbox Code Playgroud) 我正在努力研究如何最好地完成我的课程设计工作.
我的情况.
我有一个订单抽象类,其中包含2个子类所需的订单方法和信息
order_Outbound
和order_inbound
每个子类需要2个名为create和get的静态公共方法
但从我所读到的关于PHP 5.3你不能有抽象的静态方法???
所以我的想法是有一个接口Order_Interface接管该角色,但我该如何实现它.我还在父类中实现它吗?
在这种情况下,父抽象类仍然需要我在抽象类中创建一个get和create方法.或者我在孩子们中实现它并从抽象类扩展???
也!!!出站和入站子节点都需要创建静态方法,但需要传递不同的参数
我可以在界面中有公共静态函数create()
并在order_outbound中的实现声明它公共静态函数create($ address,$ reference,$ orderID)
我是PHP的新手,我正在找出实现某些数据库访问代码的最佳方法.我正在尝试创建一些简单的数据库访问对象 - 每个表都有自己的类,每个类的实例代表表中的一行,你知道这个钻取.
我的代码似乎有效,但我在网上看到的一些内容让我担心我的方法可能会以某种方式出错.因为"我可以这样做吗?" 并且"我应该这样做吗?" 是两个不同的问题,我希望一些PHP兽医可以插入.
我当前的策略是创建一个包含所有公共代码的基类抽象Table类,然后让每个表示单个表的类扩展它.
我主要担心的是这段代码:
abstract class Table {
protected abstract static function get_fields();
protected abstract static function get_primary_key();
protected abstract static function get_table_name();
Run Code Online (Sandbox Code Playgroud)
这个想法是每个实现类将定义字段名称,主键,表名等,然后Table类将使用这些函数来填充特定的空格,如下所示:
static function insert($values) {
$field_list = array();
$value_list = array();
foreach (static::get_fields() as $field_name) {
if (isset($values[$field_name])) {
$field_list[] = $field_name;
$value_list[] = self::escape($values[$field_name]);
}
}
$field_string = join(", ", $field_list);
$value_string = "'" . join("', '", $value_list) . "'";
$sql = "insert into " . static::get_table_name() . " ($field_string) values ($value_string)"; …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
abstract class ExampleClass
{
public static function regularStaticFunction()
{
return static::abstractStaticFunction();
}
abstract protected static function abstractStaticFunction();
}
ExampleClass::regularStaticFunction();
Run Code Online (Sandbox Code Playgroud)
PhpStorm IDE对声明的声明发出警告abstractStaticFunction:
PHP严格标准:静态函数'abstractStaticFunction'不应该是抽象的.
静态函数不应该是抽象的.
但是,PHP在解析此类时会继续执行程序并输出以下内容:
PHP严格标准:静态函数ExampleClass :: abstractStaticFunction()在第7行的php shell代码中不应该是抽象的
在我看来,因为PHP允许对抽象类进行静态函数调用,所以不应该在抽象类上定义抽象静态函数.
为什么解释器在PHP中允许抽象静态函数,当它们是荒谬的时候?
这个消息在php 5.4中显示了一些奇怪的原因.
我的班级看起来像这样:
abstract class model{
private static
$tableStruct = array();
abstract protected static function tableStruct();
public static function foo(){
if(!isset(self::$tableStruct[get_called_class()]))
self::$tableStruct[get_called_class()] = static::tableStruct();
// I'm using it here!!
}
}
Run Code Online (Sandbox Code Playgroud)
并应使用如下:
class page extends model{
protected static function tableStruct(){
return array(
'id' => ...
'title' => ...
);
}
...
}
Run Code Online (Sandbox Code Playgroud)
为什么制作子类所需的静态方法被认为是违反标准的?
好的,所以我在这里读了很多关于此的帖子,但我认为这是一个特定的新问题.
我希望我们这里很多人错误地称之为"抽象静态方法"的功能.那就是:我想要一个类,它坚持扩展它的类实现某些静态方法.
对于不允许抽象静态的讨论问题,似乎有两条道路,但两者似乎都不优雅.
以下内容会生成错误:"PHP严格标准:静态函数A :: fn()不应该是抽象的".
<?php
abstract class A
{
abstract static public function fn();
}
class B extends A
{
static public function fn()
{
// does something on class vars etc.
}
}
Run Code Online (Sandbox Code Playgroud)
<?php
interface iA {
static function fn();
}
abstract class A implements iA
{
} // obviously this would have other stuff in it in reality
class B extends A
{
static public function fn()
{
// does …Run Code Online (Sandbox Code Playgroud) PHP 7.1
我目前正在尝试制作一个抽象类,以提供和定义并部分实现其子类的功能。
在这里,我使用以下构造:
abstract class Parent {
public static function fromDB(string $name = '') {
$instance = new static();
if (!empty($name)) {
$instance->setName($name)->read();
}
return $instance;
}
public abstract function read();
public abstract function setName(string $name): self;
}
Run Code Online (Sandbox Code Playgroud)
在这里PHP似乎理解setName($name)返回类型为Object的Object Parent,但是PhpStorm指示read()不能在结果上调用,这将是预期的结果。
错误消息:在主题类中找不到引用的方法。
我不确定这是否是PHP或PhpStorm中的错误,或更可能是我不了解自己在做什么...
我已经阅读了“后期静态绑定”和以下部分讨论此问题的问题,但我不知道如何解决此问题:
感谢您的时间和帮助。
编辑:如下所示,我试图在子类中实现:
public function setName(string $name = null): user {...}
Run Code Online (Sandbox Code Playgroud)
这显然不适用于selfreturn,但(IMO应该)使用static,这是被禁止的。
class Foo {
public static function foobar() {
self::whereami();
}
protected static function whereami() {
echo 'foo';
}
}
class Bar extends Foo {
protected static function whereami() {
echo 'bar';
}
}
Foo::foobar();
Bar::foobar();
Run Code Online (Sandbox Code Playgroud)
预期结果foobar实际结果foofoo
更糟糕的是,服务器仅限php 5.2
我正在尝试这样做,但我没有成功.
abstract class Animal
{
abstract static function getName();
static function sayName() { echo self::getName(); }
}
Run Code Online (Sandbox Code Playgroud)
谢谢!