静态类方法在类外部调用时返回对象,但在不同类

时间:2017-06-01 23:41:12

标签: php symfony doctrine-orm doctrine

我正在经历这种非常奇怪的PHP行为,而且我有点失落。

简介:我已经使用自己的抽象类设置了Doctrine ORM,以便更容易与实体进行交互,同时享受Doctrine的优势。我知道我需要添加依赖注入,但这是一个开始。

我已经让Entity ORM调用与我从控制器脚本进行的测试非常有效,该脚本是任何类之外的普通文件。

一旦我尝试在任何其他类中进行任何实体ORM调用,它将返回一个空对象。我追溯到一个静态方法,构建EntityManager for Doctrine。这真的很奇怪;静态方法的里面我可以跟踪我正在创建/返回的对象,这很好。当我实际调用静态方法时,返回的值是一个空对象。这是一个简化的结构:

namespace MyApp\Core;

use MyApp\Core\System;
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

class SystemDBA {

public static function entityManager()
{
    $paths = array(PLATFORM_ROOT."/classes/entities");
    $isDevMode = false;

    $db_settings = System::getSystemSettings();

    $dbParams = array(
        'driver'   => 'pdo_mysql',
        'user'     => $db_settings['username'],
        'password' => $db_settings['password'],
        'dbname'   => $db_settings['database'],
    );

    $config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);

    $em = EntityManager::create($dbParams, $config);

    // this will always return the right kind of EntityManager object no matter where an entity is called from.
    error_log(json_encode($em));

    // this however is sending back an empty object when an entity is called inside of a class. 
    return $em;
}

$em return vs error_log是问题所在的地方。无论从error_log调用系统的位置始终是正确的,但返回不是。这是链的其余部分:

namespace MyApp\Entities;

use MyApp\Core\System;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

use MyApp\Core\SystemDBA;

class EntityBase
{

    public static function find($id)
    {
        $db = SystemDBA::entityManager();
        // if it's an array of ids we can try to get multiples
        $object = $db->getRepository(get_called_class())->findOneBy(['id'=>$id]);

        if ($object) return $object;

        return false;
    }

方法find()的第一行是$db是一个空对象,而不是我期望的Doctrine EntityManager对象。

编辑我已确认get_called_class()正在EntityBase中返回MyApp\\Entities\\People,无论我是从另一个类调用该实体,还是从独立的PHP文件调用该实体。所以它似乎不是存储库类名的问题。

namespace MyApp\Entities;

/**
 * @Entity
 * @Table(name="people")
 */

class People extends EntityBase {

扩展EntityBase

的简单ORM实体类

最后,如果我从这样的独立控制器调用实体:

namespace MyApp\Controllers;
use MyApp\Entities\People;

$user = People::find(123);

它工作正常,SystemDBA::entityManager()外部返回,并在内部跟踪正确的对象。

但是,如果我尝试从另一个类内部运行它,SystemDBA::entityManager()在内部跟踪正确的对象,但在外部返回一个空对象。

namespace MyApp\SomeStuff;

use MyApp\Entities\People;

class myClass {
    protected function getUser($user_id) {
        $user = People::find(123);
        }

我最初认为这与Doctrine相关,但它似乎是PHP的一些问题。我尝试将最后一个示例中的类方法更改为不受保护,但似乎没有任何影响。任何见解将不胜感激!

1 个答案:

答案 0 :(得分:1)

http://php.net/manual/en/function.get-called-class.php

  

获取调用静态方法的类的名称。

你在myClass内调用静态方法,所以它无法工作。

顺便说一下,我不建议那样做,经过一段时间你会真的后悔使用静态,引入这样的依赖。 并且你在每次调用时创建新的EntityManager实例(所以一个新的连接),这是低效的并且将破坏教义行为(你可以阅读工作单元)。

使用容器进行依赖注入是正确的方法。