我有一个扩展CComponent
class CompanyModel extends CComponent{
private $company_pk;
public function getCompany_pk()
{
return $this->company_pk;
}
public function setCompany_pk($value) {
$this->company_pk = $value;
}
}
我有一个填充此模态的函数
public function getCompanyList() {
$companyList=array();
$company_obj = new CompanyModel();
$sql = "SELECT company_pk,name FROM tbl_company WHERE status = ".Constants::ACTIVE_COMPANY;
$command=$this->connection->createCommand($sql);
$command->setFetchMode(PDO::FETCH_ASSOC);
$rows=$command->queryAll();
foreach ($rows as $row){
$company_obj->company_pk = $row['company_pk'];
array_push($companyList,$company_obj);
}
return $companyList;
}
和我的控制器
Class UserController extends CController {
public function actionGetCompanyList() {
$model = new UserAction();
$ret_val = $model->getCompanyList();
echo CJSON::encode((array)$ret_val[0]);
}
}
我得到的JSON是
{"\u0000CompanyModel\u0000company_pk":"2"}
如何删除这些垃圾值
答案 0 :(得分:1)
我认为您以后无法解码它们,如果您将$company_pk
更改为公开,它应该正确编码。问题在于您的对象强制转换为数组,这会向您的私有成员$company_pk
添加NULL字节。在echo CJSON::encode((array)$ret_val[0]);
中,因为它是OBJECTS的数组。
你可以做坏事。
$json = '{"\u0000CompanyModel\u0000company_pk":"2"}';
$json = str_replace('\u0000', '', $json);
var_dump(json_decode($json));
或者您将对象传递给CJSON::encode
我对YII知之甚少,但它应该按照手册http://www.yiiframework.com/doc/api/1.1/CJSON来处理对象。
以下是重现问题的示例:
class test {
private $private = 1;
public $publiv = 2;
}
$obj = new test();
$array = (array) $obj;
$json = json_encode($array);
var_dump($json);
var_dump(json_decode($json));
修改强>:
从手册http://www.php.net/manual/en/language.types.array.php:
如果将对象转换为数组,则结果是一个数组,其元素是对象的属性。键是成员变量名,有一些值得注意的例外:整数属性是不可访问的;私有变量的类名前置于变量名;受保护的变量在变量名前面加上'*'。这些前置值在任一侧都有空字节。
我从YII快速查看CJSON::encode
并且您可以直接使用对象,但您的对象必须是可遍历的,因此您必须实现Iterator接口。 http://www.php.net/manual/en/class.iterator.php
编辑:2
实现接口可能很棘手,还有另一个选项可以从对象内部调用get_object_vars
,在这种情况下,您将获得可以工作的数组。
class CompanyModel extends CComponent
{
private $company_pk;
public function getCompany_pk()
{
return $this->company_pk;
}
public function setCompany_pk($value)
{
$this->company_pk = $value;
}
public function export()
{
return get_object_vars($this);
}
}
然后:
$ret_val = $model->getCompanyList();
echo CJSON::encode($ret_val->export());
问题为什么它对普通对象不起作用,因为YII在内部使用get_object_vars
,当它在不同的范围内时它不能访问私有属性。
答案 1 :(得分:0)
我发现如果我在模型类中扩展CModel而不是CComponent,我可以实现我想要的。在扩展此类时,您必须覆盖一个抽象方法。否则会抛出错误。我的新Model类看起来像这样
class CompanyModel extends CModel{
private $company_pk;
public function attributeNames()
{
return array( 'company_pk' );
}
public function attributeLabels()
{
return array( 'company_pk' => 'company_pk Label' );
}
public function getCompany_pk()
{
return $this->company_pk;
}
public function setCompany_pk($value) {
$this->company_pk = $value;
}
}