Вот мой пример:
trait FileConfig {
public static function getPathForUploads() {
$paths = static::getPaths();
//etc.
}
abstract public static function getPaths(); //doesn't work. Error: "Static function SharedDefaultConfig::getPaths() should not be abstract"
abstract public function getPaths(); //OK
public static function getPaths() {} //OK
}
Учебный класс:
class AppConfig {
use FileConfig;
public static function getPaths() {
return array(...);
}
}
Вызов:
AppConfig::getPathForUploads();
Необходимо сделать его статичным и абстрактным (чтобы заставить классы использовать FileConfig реализовать getPaths).
Интересно, как можно реализовать изменение метода это статический имущество? Это хорошая практика или есть лучшие решения? Станет ли это когда-нибудь незаконным?
Спасибо
Это исправлено в php 7, поэтому работает следующий код:
<?php
error_reporting(-1);
trait FileConfig {
public static function getPathForUploads() {
echo static::getPaths();
}
abstract static function getPaths();
}
class AppConfig {
use FileConfig;
protected static function getPaths() {
return "hello world";
}
}
AppConfig::getPathForUploads();
http://sandbox.onlinephpfunctions.com/code/610f3140b056f3c3e8defb84e6b57ae61fbafbc9
Но на самом деле он не проверяет, является ли метод в AppConfig статическим или нет во время компиляции. Вы получите предупреждение только при попытке статического вызова нестатического метода: http://sandbox.onlinephpfunctions.com/code/1252f81af34f71e901994af2531104d70024a685
Вам не нужно делать метод статическим, чтобы заставить классы использовать его для реализации метода. Вы можете просто использовать интерфейсы бок о бок.
trait FileUploadConfig {
public static function getPathForUploads() {
$paths = static::getPaths();
//etc.
}
}
Черта была оставлена как есть. Я просто забрал функции для интерфейса.
interface PathConfiguration {
public static function getPaths();
}
Интерфейс заставляет класс реализовать функцию. Я оставил static
там, чтобы соответствовать спецификации черты.
class AppConfig implements PathConfiguration {
use FileUploadConfig;
public static function getPaths() {
return [];
}
}
Чтобы заставить классы, использующие FileConfig, реализовать getPaths, необязательно делать абстрактную функцию статичной. Статический означает, что он принадлежит к классу, который объявил его. Сделайте его защищенным статическим, добавьте код из черты, и тогда вы можете изменить поведение путем наследования от вашего класса AppConfig.