为什么在 cakePHP 3 中不应该调用虚拟 属性 getter?
Why a virtual property getter should not be called in cakePHP 3?
在 ctp 中,我显示了 2 个实体的多个虚拟属性,由 getters 计算。
这对两个实体之一都可以,但对于另一个实体,none 的属性 getter 永远不会被调用。
这是 ctp 的摘录:
<table>
....
<td><?= $agTheme->agthemelanguages_wc_string ?></td>
<td><?= $agPoi->paragraph_length_string ?></td>
<td><?= $agPoi->images_string ?></td>
<td><?= $agPoi->audios_string ?></td>
....
</table>
AgTheme 的 属性 没问题,但是没有 getter 的 Agpoi 属性被调用。
Agtheme 模型是:
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
use Cake\Collection\Collection;
use Cake\Core\Configure;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
class Agtheme extends Entity {
protected $_accessible = [
'site_id' => true,
'site' => true,
'name' => true,
'directory_name' => true,
'comment' => true,
'image_0' => true,
'imgpathname0' => true,
'imgfile0' => true,
'mobile_theme' => true,
'agthemelanguages' => true,
'poi_by_tag' => true,
'poi_to_map' => true,
'unlock_mode' => true,
'unlock_code' => true,
'published' => true,
'approved' => true,
];
protected function _getAgthemelanguagesWcString() {
if (isset($this->_properties['agthemelanguages_wc_string'])) {
return $this->_properties['agthemelanguages_wc_string'];
}
if (empty($this->agthemelanguages)) {
return '';
}
$agthemelanguages = new Collection($this->agthemelanguages);
$str = $agthemelanguages->reduce(function ($string, $agthemelanguage) {
return $string . $agthemelanguage->language->name_fr . ' :<br/>';
}, '');
return trim($str, '<br/>');
}
function _getImgpathname0() {
if (isset($this->_properties['imgpathname0'])) {
return $this->_properties['imgpathname0'];
}
if (!isset($this->_properties['id']) || empty($this->image_0) || !isset($this->_properties['directory_name'])) {
return '';
}
$img_path = SITES_CONTENT_URL . $this->_properties['directory_name'] .'/imgTheme_0.' . $this->_properties['image_0'];
return $img_path;
}
}
而Agpoi模型是(Agpoi.php):
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
use Cake\Collection\Collection;
class Agpoi extends Entity
{
protected $_accessible = [
'name' => true,
'latitude' => true,
'longitude' => true,
'bearing' => true,
'preload' => true,
'agtheme' => true,
'agpoiaudios' => true,
'agpoiimages' => true,
'agpoitextes' => true,
'agpoiwaypoints' => true,
];
protected function _getImagesString()
{
if (isset($this->_properties['images_string'])) {
return $this->_properties['images_string'];
}
if (empty($this->agpoiimages)) {
return '';
}
$agpoiimages = new Collection($this->agpoiimages);
$str = $agpoiimages->reduce(function ($string, $agpoiimage)
{
return $string . $agpoiimage->image . ', ';
}, '');
return trim($str, ', ');
}
protected function _getAudiosString()
{
if (isset($this->_properties['audios_string'])) {
return $this->_properties['audios_string'];
}
if (empty($this->agpoiaudios)) {
return '';
}
$agpoiaudios = new Collection($this->agpoiaudios);
$str = $agpoiaudios->reduce(function ($string, $agpoiaudio)
{
return $string . $agpoiaudio->filename . ', ';
}, '');
return trim($str, ', ');
}
protected function _getParagraphLengthString() {
if (isset($this->_properties['paragraph_length_string'])) {
return $this->_properties['paragraph_length_string'];
}
if (empty($this->agpoitextes)) {
return '';
}
$agpoitextes = new Collection($this->agpoitextes);
$str = $agpoitextes->reduce(function ($string, $agpoitexte) {
return $string . str_word_cound($agpoitexte->paragraph) . __(" mots<br/>");
}, '');
return trim($str, '<br/>');
}
}
不幸的是,我怀疑问题可能来自上面的代码,我最好想想其他地方的愚蠢错误,但我真的想知道是什么导致了这样的问题,这是我的问题:
谁能告诉我什么让蛋糕找一个getter?
什么可以阻止蛋糕调用 getter??
我想最后一个问题的答案并不明显,但任何提示都将不胜感激...
编辑
@ndm
调试(get_class($agPoi));
'Cake\ORM\Entity'
而
调试(get_class($agTheme));
'App\Model\Entity\Agtheme'
很明显 Agpoi 没有明确定义,但我不明白为什么...
编辑 2
Table 是 (AgpoisTable.php):
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* Agpois Model
*/
class AgpoisTable extends Table {
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config) {
$this->table('agpois');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsToMany('Agthemes', [
'foreignKey' => 'agpoi_id',
'targetForeignKey' => 'agtheme_id',
'joinTable' => 'agthemes_agpois',
'dependent' => true,
]);
$this->hasMany('Agpoiaudios', [
'dependent' => true,
'foreignKey' => 'agpoi_id',
]);
$this->hasMany('Agpoiimages', [
'dependent' => true,
'foreignKey' => 'agpoi_id',
]);
$this->hasMany('Agpoitextes', [
'dependent' => true,
'foreignKey' => 'agpoi_id',
]);
$this->hasMany('Agpoiwaypoints', [
'dependent' => true,
'foreignKey' => 'agpoi_id',
]);
}
public function validationDefault(Validator $validator) {
$validator
....
return $validator;
}
}
我还到处搜索 'agpoi' 以防万一....没有意外的其他 agpoi 类名或类似的东西。
debug($this->Agpois);
object(App\Model\Table\AgpoisTable) {
'registryAlias' => 'Agpois',
'table' => 'agpois',
'alias' => 'Agpois',
'entityClass' => '\Cake\ORM\Entity',
'associations' => [
(int) 0 => 'agthemes',
(int) 1 => 'agpoiaudios',
(int) 2 => 'agpoiimages',
(int) 3 => 'agpoitextes',
(int) 4 => 'agpoiwaypoints',
(int) 5 => 'agthemesagpois'
],
'behaviors' => [],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
当然是entityClass的问题。
这里的问题似乎是 table class 的名称,分别是实体 class 的名称,可能取决于您的观点。
默认情况下,相应实体class的名称是通过使用没有尾随Table
的单数tableclass名称来猜测的,但是Agpois
不会像您假设的那样变形为 Agpoi
,而只是 Agpois
,因此它正在寻找不存在的 class App\Model\Entity\Agpois
,因此回退到默认实体库 class.
我不确定 Agpois
是什么意思,它源于哪种语言,但它肯定不是英语,因此此类问题并不意外,因为 Inflector 只能处理英语单词.
tl;博士
如果您必须使用名称 Apgois
,那么您必须在 table 的 initialize()
方法中手动定义实体的名称 class :
public function initialize(array $config)
{
// ...
$this->entityClass('Apgoi');
// ...
}
或配置变形器使其可以处理该词:
Inflector::rules('irregular', ['apgoi' => 'apgois']);
或者甚至将实体 class 重命名为 Apgois
(如果适用且不会导致任何命名冲突)。
另见
在 ctp 中,我显示了 2 个实体的多个虚拟属性,由 getters 计算。 这对两个实体之一都可以,但对于另一个实体,none 的属性 getter 永远不会被调用。
这是 ctp 的摘录:
<table>
....
<td><?= $agTheme->agthemelanguages_wc_string ?></td>
<td><?= $agPoi->paragraph_length_string ?></td>
<td><?= $agPoi->images_string ?></td>
<td><?= $agPoi->audios_string ?></td>
....
</table>
AgTheme 的 属性 没问题,但是没有 getter 的 Agpoi 属性被调用。
Agtheme 模型是:
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
use Cake\Collection\Collection;
use Cake\Core\Configure;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
class Agtheme extends Entity {
protected $_accessible = [
'site_id' => true,
'site' => true,
'name' => true,
'directory_name' => true,
'comment' => true,
'image_0' => true,
'imgpathname0' => true,
'imgfile0' => true,
'mobile_theme' => true,
'agthemelanguages' => true,
'poi_by_tag' => true,
'poi_to_map' => true,
'unlock_mode' => true,
'unlock_code' => true,
'published' => true,
'approved' => true,
];
protected function _getAgthemelanguagesWcString() {
if (isset($this->_properties['agthemelanguages_wc_string'])) {
return $this->_properties['agthemelanguages_wc_string'];
}
if (empty($this->agthemelanguages)) {
return '';
}
$agthemelanguages = new Collection($this->agthemelanguages);
$str = $agthemelanguages->reduce(function ($string, $agthemelanguage) {
return $string . $agthemelanguage->language->name_fr . ' :<br/>';
}, '');
return trim($str, '<br/>');
}
function _getImgpathname0() {
if (isset($this->_properties['imgpathname0'])) {
return $this->_properties['imgpathname0'];
}
if (!isset($this->_properties['id']) || empty($this->image_0) || !isset($this->_properties['directory_name'])) {
return '';
}
$img_path = SITES_CONTENT_URL . $this->_properties['directory_name'] .'/imgTheme_0.' . $this->_properties['image_0'];
return $img_path;
}
}
而Agpoi模型是(Agpoi.php):
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
use Cake\Collection\Collection;
class Agpoi extends Entity
{
protected $_accessible = [
'name' => true,
'latitude' => true,
'longitude' => true,
'bearing' => true,
'preload' => true,
'agtheme' => true,
'agpoiaudios' => true,
'agpoiimages' => true,
'agpoitextes' => true,
'agpoiwaypoints' => true,
];
protected function _getImagesString()
{
if (isset($this->_properties['images_string'])) {
return $this->_properties['images_string'];
}
if (empty($this->agpoiimages)) {
return '';
}
$agpoiimages = new Collection($this->agpoiimages);
$str = $agpoiimages->reduce(function ($string, $agpoiimage)
{
return $string . $agpoiimage->image . ', ';
}, '');
return trim($str, ', ');
}
protected function _getAudiosString()
{
if (isset($this->_properties['audios_string'])) {
return $this->_properties['audios_string'];
}
if (empty($this->agpoiaudios)) {
return '';
}
$agpoiaudios = new Collection($this->agpoiaudios);
$str = $agpoiaudios->reduce(function ($string, $agpoiaudio)
{
return $string . $agpoiaudio->filename . ', ';
}, '');
return trim($str, ', ');
}
protected function _getParagraphLengthString() {
if (isset($this->_properties['paragraph_length_string'])) {
return $this->_properties['paragraph_length_string'];
}
if (empty($this->agpoitextes)) {
return '';
}
$agpoitextes = new Collection($this->agpoitextes);
$str = $agpoitextes->reduce(function ($string, $agpoitexte) {
return $string . str_word_cound($agpoitexte->paragraph) . __(" mots<br/>");
}, '');
return trim($str, '<br/>');
}
}
不幸的是,我怀疑问题可能来自上面的代码,我最好想想其他地方的愚蠢错误,但我真的想知道是什么导致了这样的问题,这是我的问题:
谁能告诉我什么让蛋糕找一个getter? 什么可以阻止蛋糕调用 getter??
我想最后一个问题的答案并不明显,但任何提示都将不胜感激...
编辑
@ndm 调试(get_class($agPoi)); 'Cake\ORM\Entity'
而 调试(get_class($agTheme)); 'App\Model\Entity\Agtheme'
很明显 Agpoi 没有明确定义,但我不明白为什么...
编辑 2 Table 是 (AgpoisTable.php):
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* Agpois Model
*/
class AgpoisTable extends Table {
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config) {
$this->table('agpois');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsToMany('Agthemes', [
'foreignKey' => 'agpoi_id',
'targetForeignKey' => 'agtheme_id',
'joinTable' => 'agthemes_agpois',
'dependent' => true,
]);
$this->hasMany('Agpoiaudios', [
'dependent' => true,
'foreignKey' => 'agpoi_id',
]);
$this->hasMany('Agpoiimages', [
'dependent' => true,
'foreignKey' => 'agpoi_id',
]);
$this->hasMany('Agpoitextes', [
'dependent' => true,
'foreignKey' => 'agpoi_id',
]);
$this->hasMany('Agpoiwaypoints', [
'dependent' => true,
'foreignKey' => 'agpoi_id',
]);
}
public function validationDefault(Validator $validator) {
$validator
....
return $validator;
}
}
我还到处搜索 'agpoi' 以防万一....没有意外的其他 agpoi 类名或类似的东西。
debug($this->Agpois);
object(App\Model\Table\AgpoisTable) {
'registryAlias' => 'Agpois',
'table' => 'agpois',
'alias' => 'Agpois',
'entityClass' => '\Cake\ORM\Entity',
'associations' => [
(int) 0 => 'agthemes',
(int) 1 => 'agpoiaudios',
(int) 2 => 'agpoiimages',
(int) 3 => 'agpoitextes',
(int) 4 => 'agpoiwaypoints',
(int) 5 => 'agthemesagpois'
],
'behaviors' => [],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
当然是entityClass的问题。
这里的问题似乎是 table class 的名称,分别是实体 class 的名称,可能取决于您的观点。
默认情况下,相应实体class的名称是通过使用没有尾随Table
的单数tableclass名称来猜测的,但是Agpois
不会像您假设的那样变形为 Agpoi
,而只是 Agpois
,因此它正在寻找不存在的 class App\Model\Entity\Agpois
,因此回退到默认实体库 class.
我不确定 Agpois
是什么意思,它源于哪种语言,但它肯定不是英语,因此此类问题并不意外,因为 Inflector 只能处理英语单词.
tl;博士
如果您必须使用名称 Apgois
,那么您必须在 table 的 initialize()
方法中手动定义实体的名称 class :
public function initialize(array $config)
{
// ...
$this->entityClass('Apgoi');
// ...
}
或配置变形器使其可以处理该词:
Inflector::rules('irregular', ['apgoi' => 'apgois']);
或者甚至将实体 class 重命名为 Apgois
(如果适用且不会导致任何命名冲突)。
另见