我正在经历这种非常奇怪的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
最后,如果我从这样的独立控制器调用实体:
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的一些问题。我尝试将最后一个示例中的类方法更改为不受保护,但似乎没有任何影响。任何见解将不胜感激!
答案 0 :(得分:1)
http://php.net/manual/en/function.get-called-class.php
获取调用静态方法的类的名称。
你在myClass
内调用静态方法,所以它无法工作。
顺便说一下,我不建议那样做,经过一段时间你会真的后悔使用静态,引入这样的依赖。
并且你在每次调用时创建新的EntityManager
实例(所以一个新的连接),这是低效的并且将破坏教义行为(你可以阅读工作单元)。
使用容器进行依赖注入是正确的方法。