【问题标题】:Why a virtual property getter should not be called in cakePHP 3?为什么不应该在 cakePHP 3 中调用虚拟属性 getter?
【发布时间】:2015-05-17 12:36:18
【问题描述】:

在一个 ctp 中,我显示了来自 2 个实体的几个虚拟属性,由 getter 计算。 两个实体中的一个都可以,但另一个实体永远不会调用任何属性 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 的属性没问题,但是没有调用 Agpoi 的属性的 getter。

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/>');

    }
}

不幸的是,我怀疑问题可能来自上面的代码,我最好考虑一下其他地方的愚蠢错误,但我真的想知道是什么导致了这样的问题,这是我的问题:

谁能告诉我是什么让蛋糕寻找吸气剂? 什么可以阻止蛋糕调用吸气剂?

我猜最后一个问题的答案并不明显,但任何提示都将不胜感激......

编辑

@ndm 调试(get_class($agPoi)); 'Cake\ORM\Entity'

而 调试(get_class($agTheme)); '应用\模型\实体\Agtheme'

很明显,Agpoi 的定义不明确,但我不明白为什么......

编辑 2 表是(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 的问题总是如此。

【问题讨论】:

  • debug(get_class($agPoi)); 说什么?
  • 问题可能是某个地方的命名问题。对应的表类叫什么?表和实体类的文件名是什么? debug($tableInstance); 是否为 entityClass 显示正确的类名? ps,请使用带有@username标签的cmets来通知用户,我只是偶然看到你的编辑。
  • @ndm 感谢您的帮助,我刚刚添加了请求的信息。

标签: cakephp models cakephp-3.0


【解决方案1】:

这里的问题似乎是表类的名称,分别是实体类的名称,可能取决于您的观点。

默认情况下,相应实体类的名称是通过使用不带尾随Table 的单数表类名称来猜测的,但是Agpois 不会像您假设的那样变形为Agpoi,而只是@ 987654326@,因此它正在寻找不存在的类App\Model\Entity\Agpois,因此回退到默认实体基类。

我不确定Agpois 是什么意思,以及它源自哪种语言,但肯定不是英语,因此这些问题并不意外,因为 Inflector 只能处理英语单词。

tl;博士

如果您必须使用名称 Apgois,那么您必须在表中手动定义实体类的名称 initialize() 方法:

public function initialize(array $config)
{
    // ...
    $this->entityClass('Apgoi');
    // ...
}

或配置变形器以便它可以处理该词:

Inflector::rules('irregular', ['apgoi' => 'apgois']);

或者甚至将实体类重命名为Apgois(如果适用并且不会导致任何命名冲突)。

另见

【讨论】:

  • 非常好!我又在 cakePHP 中学到了一些东西,当然 agpoi 是一个首字母缩写词,而不是一个英文单词,但我没有足够注意它仅管理英语单词的复数/单数的方式的屈折变化,因此,有效地,在这种情况下它不能猜猜应该如何命名模型。它还解释了为什么我必须在关联中指定 'foreignKey' => 'agpoi_id'。没有它,cake 在查询中使用了 agpoi_id 而不是我期望看到的 agpoi_id。非常非常好ndm!!!! $this->entityClass('Apgoi');就我而言,这似乎是一个好方法。
猜你喜欢
  • 2010-09-24
  • 1970-01-01
  • 2011-11-07
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多