假设我有以下代码:
首先,我创建了父母
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
国家:
人口国家:
语言:
我想保留父级的方法,但不保留父级的属性。我该如何实现?
David在评论中告诉我将属性设置为Private。我这样做了,但效果很好,但是当我创建Country对象时,它将在子类中打印父级的属性。
这是代码,当父属性为Public时,将为我提供此输出。
人口总数:10000
国家:
人口国家:
语言:
国家:英格兰
人口国家:30000
语言:英语
它应该打印:
人口总数:10000
国家:英格兰
人口国家:30000
语言:英语
当我将它们设置为“私人”时,我会得到:
致命错误:未捕获错误:无法访问私有属性国家:: $ C:\ xampp \ htdocs \ ejercicios.php:141中的语言堆栈堆栈:#0 {main}抛出了C:\ xampp \ htdocs \ ejercicios。第141行上的php
当我将它们设置为“受保护”时,我得到了:
致命错误:未捕获错误:无法访问受保护的属性国家:: $ C:\ xampp \ htdocs \ ejercicios.php:141中的堆栈跟踪:#0 {main}抛出了C:\ xampp \ htdocs \ ejercicios。第141行上的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>';
}
}
答案 0 :(得分:0)
看起来像一个错误的设计模式。对我来说,一个国家可以包含几个不同的城市。因此,城市不是国家。您的国家/地区实体类不应该是这样吗?
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());
希望这会有所帮助。
答案 1 :(得分:0)
您可以使用Reflection来实现。
Reflection 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>';
}
}