是否可以 'auto-declare' 一个 parent class 属性 每个 child class?
Is it possible to 'auto-declare' a parent class property for every child class?
假设我有一个库 class 和一个自动加载器,其中包含 classes
目录中以 MyLibrary_
开头的任何 class:
spl_autoload_register(
function ($classname) {
if(class_exists($classname)) return;
if(strpos($classname, 'MyLibrary_') !== 0) return;
//if such class exists, include it
$class_file = __DIR__.'/classes/'.$classname.'.php';
if(file_exists($class_file)){
include $class_file;
}
}
);
if(!class_exists('Someprefix_MyLibrary')){
class Someprefix_MyLibrary{}
}
$mylibrary = new Someprefix_MyLibrary;
然后,在/classes/strings.php
文件中有一个childclassMyLibrary_strings:
class MyLibrary_strings extends Someprefix_MyLibrary{
public punction __construct(){
$this->strings = new self(); //not declared in parent class
}
//make first letter capital in a multi-byte string
public function mb_ucfirst($string, $encoding){
$firstChar = mb_substr($string, 0, 1, $encoding);
$then = mb_substr($string, 1, null, $encoding);
return mb_strtoupper($firstChar, $encoding) . $then;
}
}
我想做这样的事情:
$new_string = $mylibrary->strings->mb_ucfirst('somestring');
除非我在 parent class 中声明 public $strings
,否则我的 IDE 会警告我 属性 已被动态声明,而在其他 child classes,strings
属性 将被标记为未找到。我想要的是 自动 包含一个 parent 属性 用于每个已放入 classes
目录的文件或每个 child class of Someprefix_MyLibrary
,无需手动声明每个 属性.
是否可以做到,怎么做?
您可以像这样使用 php 中的 __get 魔法方法来实现。
在你的 parent class 中,添加一个 __get
方法:
class Someprefix_MyLibrary{
public function __get(string $name)
{
return $this->{$name} = null;
}
}
并在 child class:
中调用您需要的任何未声明的 属性
class MyLibrary_strings extends Someprefix_MyLibrary{
public function undeclaredProperty(){
return $this->string;
}
}
注意:因此,当调用任何未声明的属性时,我们将陷入__get魔术方法,我们将声明它并return它。
您是否考虑过改用命名空间和静态方法?
您将不得不更改您的 auto-loading,但类似于:
// MyLibrary_Strings.php
namespace MyLibrary {
class Strings {
public static function mb_ucfirst($string, $encoding) {
$firstChar = mb_substr($string, 0, 1, $encoding);
$then = mb_substr($string, 1, null, $encoding);
return mb_strtoupper($firstChar, $encoding) . $then;
}
}
}
// MyLibrary_Arrays.php
namespace MyLibrary {
class Arrays {
public static function first($array) {
return $array[0];
}
}
}
// some other code
$result = MyLibrary\String::mb_ucfirst($string, $encoding);
$first_item = MyLibrary\Array::first(["a", "b", "c"]);
假设我有一个库 class 和一个自动加载器,其中包含 classes
目录中以 MyLibrary_
开头的任何 class:
spl_autoload_register(
function ($classname) {
if(class_exists($classname)) return;
if(strpos($classname, 'MyLibrary_') !== 0) return;
//if such class exists, include it
$class_file = __DIR__.'/classes/'.$classname.'.php';
if(file_exists($class_file)){
include $class_file;
}
}
);
if(!class_exists('Someprefix_MyLibrary')){
class Someprefix_MyLibrary{}
}
$mylibrary = new Someprefix_MyLibrary;
然后,在/classes/strings.php
文件中有一个childclassMyLibrary_strings:
class MyLibrary_strings extends Someprefix_MyLibrary{
public punction __construct(){
$this->strings = new self(); //not declared in parent class
}
//make first letter capital in a multi-byte string
public function mb_ucfirst($string, $encoding){
$firstChar = mb_substr($string, 0, 1, $encoding);
$then = mb_substr($string, 1, null, $encoding);
return mb_strtoupper($firstChar, $encoding) . $then;
}
}
我想做这样的事情:
$new_string = $mylibrary->strings->mb_ucfirst('somestring');
除非我在 parent class 中声明 public $strings
,否则我的 IDE 会警告我 属性 已被动态声明,而在其他 child classes,strings
属性 将被标记为未找到。我想要的是 自动 包含一个 parent 属性 用于每个已放入 classes
目录的文件或每个 child class of Someprefix_MyLibrary
,无需手动声明每个 属性.
是否可以做到,怎么做?
您可以像这样使用 php 中的 __get 魔法方法来实现。
在你的 parent class 中,添加一个 __get
方法:
class Someprefix_MyLibrary{
public function __get(string $name)
{
return $this->{$name} = null;
}
}
并在 child class:
中调用您需要的任何未声明的 属性class MyLibrary_strings extends Someprefix_MyLibrary{
public function undeclaredProperty(){
return $this->string;
}
}
注意:因此,当调用任何未声明的属性时,我们将陷入__get魔术方法,我们将声明它并return它。
您是否考虑过改用命名空间和静态方法?
您将不得不更改您的 auto-loading,但类似于:
// MyLibrary_Strings.php
namespace MyLibrary {
class Strings {
public static function mb_ucfirst($string, $encoding) {
$firstChar = mb_substr($string, 0, 1, $encoding);
$then = mb_substr($string, 1, null, $encoding);
return mb_strtoupper($firstChar, $encoding) . $then;
}
}
}
// MyLibrary_Arrays.php
namespace MyLibrary {
class Arrays {
public static function first($array) {
return $array[0];
}
}
}
// some other code
$result = MyLibrary\String::mb_ucfirst($string, $encoding);
$first_item = MyLibrary\Array::first(["a", "b", "c"]);