假设我有以下代码:
首先我创建了父级
class Country {
public $country;
public $populationcountry;
public $language;
使用一些方法(与此问题无关)
public function function1() { }
public function function2() { }
.
.
} //end of parent class
然后我创建孩子
Class city extends Country
{
public $populationcity;
}
然后我创建对象(在这个例子中,我只创建了一个)
$city1 = new city();
$city1->populationcity = 10000;
和对象数组
$cities = [$city1];
最后,我只想"回响"孩子的财产(人口城市)
foreach ($cities as $city) {
foreach ($city as $k => $v) {
$city->populationcity;
echo $k . ': ' . $v . '<br>';
}
}
输出:人口城市:10000
国家:人口国家:语言:
我想保留父项的方法,但不保留父项的属性。我怎样才能做到这一点?
大卫在评论中告诉我将属性设置为私有。我这样做了,它工作正常,但是当我创建一个 Country 对象时,它会在子类中打印父类的属性。
这是代码,当父属性为 Public 时,它为我提供了此输出。
人口城市: 10000 国家:人口国家:语言:国家:英格兰
人口国家: 30000
语言:
英语
它应该打印:
人口城市: 10000 国家:英格兰
人口国家: 30000
语言: 英语
当我将它们设置为"私人"时,我得到这个:
致命错误:未捕获错误:无法访问私有财产 国家::$language 在 C:\xampp\htdocs\ejercicios.php:141 堆栈跟踪:#0 {main} 在第 141 行的 C:\xampp\htdocs\ejercicios.php 中抛出
当我将它们设置为受保护时,我得到这个:
致命错误:未捕获错误:无法访问受保护的属性 国家::$language 在 C:\xampp\htdocs\ejercicios.php:141 堆栈跟踪:#0 {main} 在第 141 行抛出 C:\xampp\htdocs\ejercicios.php
class Country {
public $country;
public $populationcountry;
public $language;
}
Class city extends Country
{
public $populationcity;
}
$country1 = new Country();
$country1->language = 'English';
$country1->country = 'ENgland';
$country1->populationcountry = 30000;
$countries = [$country1];
$city1 = new city();
$city1->populationcity = 10000;
$cities = [$city1];
foreach ($cities as $city) {
foreach ($city as $k => $v) {
$city->populationcity;
echo $k . ': ' . $v . '<br>';
}
}
foreach ($countries as $country) {
foreach ($country as $k => $v) {
$country->language;
$country->populationcountry;
$country->country;
echo $k . ': ' . $v . '<br>';
}
}
看起来像一个糟糕的设计模式。对我来说,一个国家可以包含几个不同的城市。因此,城市不是一个国家。您的国家/地区实体类不应该看起来像这样吗?
class Country
{
/**
* Collection of City objects
* @var ArrayObject
*/
protected $cities;
protected $name;
protected $population;
protected $language;
public function setCity(City $city) : self
{
if ($this->cities == null) {
$this->cities = new ArrayObject();
}
$this->cities->append($city);
return $this;
}
public function getCities() : ArrayObject
{
if ($this->cities == null) {
$this->cities = new ArrayObject();
}
return $this->cities;
}
}
无论如何。。。让我们用PHP自己的反射类来解决你的问题。要获取声明类的属性,只需在 city 类中实现以下函数。
class City extends Country
{
public $populationCity;
public function getData() : array
{
$data = [];
$reflection = new ReflectionClass($this);
$properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);
foreach ($properties as $property) {
if ($property->getDeclaringClass() == $reflection) {
$data[$property->getName()] = $property->getValue($this);
}
}
return $data;
}
}
有了这个,您只能获取City
类的属性。让我们试一试...
$city = new City();
$city->populationCity = 10000;
var_dump($city->getData());
希望这有帮助。
您可以使用反射来实现此目的。
反射 API,增加了对类进行逆向工程的功能, 接口、函数、方法和扩展。此外, 反射 API 提供了检索函数的文档注释的方法, 类和方法。
这将允许您枚举属性,并查看任何给定的属性是在类本身中还是在其继承链中定义的。
foreach ($cities as $city) {
/* You can move this logic out of the loop and cache the properties
if your array contains only elements of the same type */
$reflector = new ReflectionClass($city);
$class = $reflector->getName(); // Get the name of the current class
$ownProperties = array_map(function ($e) { return $e->name; }, // Return only the name of
// the property
array_filter($reflector->getProperties(), // Return properties defined in
// the same class only, regardless the visibility, since protected properties can
// either be declared or inherited
// Check if declaring class is the same as this type
function($e) use ($class) { return $class === $e->class; } ));
/* **** */
foreach ($ownProperties as $property) {
echo $property . ': ' . $city->$property . '<br>';
}
}
演示