我正在尝试创建一个可以遍历其属性的PHP(5)对象,仅根据其公共属性而不是私有属性构建SQL查询。
由于这个父对象方法将由子对象使用,我不能简单地选择按名称跳过私有属性(我不知道它们在子对象中是什么)。
是否有一种简单的方法可以从对象中检测哪些属性是私有的?
这是我到目前为止所得到的简化示例,但此输出包含$ bar的值:
class testClass {
public $foo = 'foo';
public $fee = 'fee';
public $fum = 'fum';
private $bar = 'bar';
function makeString()
{
$string = "";
foreach($this as $field => $val) {
$string.= " property '".$field."' = '".$val."' <br/>";
}
return $string;
}
}
$test = new testClass();
echo $test->makeString();
给出输出:
property 'foo' = 'foo'
property 'fee' = 'fee'
property 'fum' = 'fum'
property 'bar' = 'bar'
我希望它不包括'bar'。
如果有更好的方法来迭代对象的公共属性,那么这也适用。
答案 0 :(得分:18)
从http://php.net/manual/reflectionclass.getproperties.php#93984
检查此代码 public function listProperties() {
$reflect = new ReflectionObject($this);
foreach ($reflect->getProperties(ReflectionProperty::IS_PUBLIC /* + ReflectionProperty::IS_PROTECTED*/) as $prop) {
print $prop->getName() . "\n";
}
}
答案 1 :(得分:12)
您可以使用Reflection来检查类的属性。要仅获取公共属性和受保护属性,请为ReflectionClass::getProperties
方法配置合适的过滤器。
以下是使用它的makeString
方法的简要示例。
public function makeString()
{
$string = "";
$reflection = new ReflectionObject($this);
$properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);
foreach ($properties as $property) {
$name = $property->getName();
$value = $property->getValue($this);
$string .= sprintf(" property '%s' = '%s' <br/>", $name, $value);
}
return $string;
}
答案 2 :(得分:4)
我找到了一个更快的解决方案:
class Extras
{
public static function get_vars($obj)
{
return get_object_vars($obj);
}
}
然后调用testClass:
$vars = Extras::get_vars($this);
答案 3 :(得分:2)
如果在迭代之前将对象强制转换为数组,则私有成员和受保护成员将具有特殊前缀:
class Test{
public $a = 1;
private $b = 1;
protected $c = 1;
}
$a = new Test();
var_dump((array) $a);
显示:
array(3) {
["a"]=>
int(1)
["Testb"]=>
int(1)
["*c"]=>
int(1)
}
也有隐藏的字符,不显示。但是你可以编写代码来检测它们。例如,正则表达式/\0\*\0(.*)$/
将匹配受保护的密钥,/\0.*\0(.*)$/
将匹配私有密钥。在两者中,第一个捕获组与成员名称匹配。
答案 4 :(得分:1)
foreach (get_class_vars(get_class($this)) ....
答案 5 :(得分:1)
您可以使用数组存储公共属性,添加一些包装器方法并使用数组将数据插入SQL。
答案 6 :(得分:1)
$propertyName = 'bar';
if(in_array(propertyName, array_keys(get_class_vars(get_class($yourObject))))) {
}
答案 7 :(得分:0)
您可以使用Reflection API检查属性的可见性:
$rp = new \ReflectionProperty($object,$property);
if($rp->isPrivate) {
// Run if the property is private
} else {
// Run if the property is Public or Protected
}