问题
I use Zendframework 3 and I have followed the tutorial for User authentication. In this project I'm able to connect to my database using entityManager. Then I created another project and copied the required code to make ORM work but I'm not able to retrieve information.
I have read my code 1000 time, no error in log, every factory is correctly mapped.
Here's my configuration:
composer.json
{
"name": "zendframework/skeleton-application",
"description": "Skeleton Application for Zend Framework zend-mvc applications",
"type": "project",
"license": "BSD-3-Clause",
"keywords": [
"framework",
"mvc",
"zf"
],
"homepage": "http://framework.zend.com/",
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"php": "^5.6 || ^7.0",
"ext-gd": "*",
"ext-intl": "*",
"zendframework/zend-component-installer": "^1.0 || ^0.3 || ^1.0.0-dev@dev",
"zendframework/zend-mvc": "^3.0.1",
"zfcampus/zf-development-mode": "^3.0",
"zendframework/zend-mvc-form": "^1.0",
"zendframework/zend-mvc-plugins": "^1.0.1",
"zendframework/zend-session": "^2.7.1",
"zendframework/zend-authentication": "^2.5",
"doctrine/doctrine-orm-module": "1.1.5",
"doctrine/doctrine-module": "dev-master",
"doctrine/migrations": "^1.4",
"zendframework/zend-math": "^3.0",
"zendframework/zend-crypt": "^3.1",
"zendframework/zend-captcha": "^2.6",
"zendframework/zend-mail": "^2.8"
},
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/"
}
},
"autoload-dev": {
"psr-4": {
"ApplicationTest\\": "module/Application/test/"
}
},
"extra": [],
"scripts": {
"development-disable": "zf-development-mode disable",
"development-enable": "zf-development-mode enable",
"development-status": "zf-development-mode status",
"serve": "php -S 0.0.0.0:8080 -t public/ public/index.php"
}
}
module.config.php
<?php
/**
* @link http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Application;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
return [
'router' => [
'routes' => [
// .. OTHER ROUTES
'tienda' => [
'type' => Segment::class,
'options' => [
'route' => '/tienda[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[a-zA-Z0-9_-]*',
],
'defaults' => [
'controller' => Controller\TiendaController::class,
'action' => 'tienda',
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\IndexController::class => Controller\Factory\IndexControllerFactory::class,
Controller\TiendaController::class => Controller\Factory\TiendaControllerFactory::class,
Controller\BlogController::class => InvokableFactory::class,
],
],
'service_manager' => [
'factories' => [
Service\MailSender::class => InvokableFactory::class,
Service\ImageManager::class => InvokableFactory::class,
],
],
// The following registers our custom view
// helper classes in view plugin manager.
'view_helpers' => [
'factories' => [
View\Helper\Menu::class => InvokableFactory::class,
View\Helper\Breadcrumbs::class => InvokableFactory::class,
],
'aliases' => [
'mainMenu' => View\Helper\Menu::class,
'pageBreadcrumbs' => View\Helper\Breadcrumbs::class,
],
],
'view_manager' => [
/*
* You typically set the display_not_found_reason and display_exceptions
* parameters to false in production systems, because you don't want site
* visitors see the details about errors in your site. However, you will
* still be able to retrieve the detailed information from Apache's
* error.log file.
*/
'display_not_found_reason' => false,
'display_exceptions' => false,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => [
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
],
'doctrine' => [
'driver' => [
__NAMESPACE__ . '_driver' => [
'class' => AnnotationDriver::class,
'cache' => 'array',
'paths' => [__DIR__ . '/../src/Entity']
],
'orm_default' => [
'drivers' => [
__NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
]
]
]
]
];
Factory
<?php
namespace Application\Controller\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\Session\SessionManager;
use Application\Service\MailSender;
use Application\Controller\TiendaController;
/**
* This is the factory for UserController. Its purpose is to instantiate the
* controller and inject dependencies into it.
*/
class TiendaControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$mailSender = $container->get(MailSender::class);
$sessionContainer = $container->get(SessionManager::class);
$entityManager = $container->get('doctrine.entitymanager.orm_default');
// Instantiate the controller and inject dependencies
return new TiendaController($mailSender, $entityManager, $sessionContainer);
}
}
TiendaController.php
<?php
namespace Application\Controller;
use Zend\Mail;
use Zend\Mvc\Controller\AbstractActionController;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Zend\View\Model\ViewModel;
use Application\Entity\User;
// use Zend\Session\Container; // We need this when using sessions
use Zend\View\Model\JsonModel;
use Application\Entity\Categoria;
use Application\Entity\Producto;
use Application\Entity\Marca;
class TiendaController extends AbstractActionController
{
/**
* Session manager.
* @var Zend\Session\SessionManager
*/
private $sessionManager;
/**
* Mail sender.
* @var Application\Service\MailSender
*/
private $mailSender;
/**
* Entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* Constructor.
*/
public function __construct($mailSender, $entityManager, $sessionManager)
{
$this->mailSender = $mailSender;
$this->entityManager = $entityManager;
$this->sessionManager = $sessionManager;
}
public function tiendaAction()
{
return new ViewModel();
}
public function categoryAction()
{
// Checks if this is a Javascript request
$xmlHttpRequst = $this->getRequest()->isXmlHttpRequest();
if ($xmlHttpRequst) {
$titles = [];
for ($i = 0; $i < 10; $i++) {
$titles[] = "Lorem ipsum dolor {$i}";
}
$view = new JsonModel($titles);
/**
* Tell the renderer not to show the layout
* by setting setTerminal to true
*/
$view->setTerminal(true);
} else {
// IS NOT THROWING AN ERROR AND IT RETURNS AN EMPTY ARRAY
$categories = $this->entityManager->getRepository(Categoria::class)->findAll();
$brands = $this->entityManager->getRepository(Marca::class)->findAll();
return new ViewModel(array(
'categories' => $categories,
'brands' => $brands
));
}
return $view;
}
public function getProductosAction()
{
// Checks if this is a Javascript request
$xmlHttpRequst = $this->getRequest()->isXmlHttpRequest();
if (! $xmlHttpRequst) {
die('Bad request');
}
$categoryId = $this->request->getPost('categoryId');
$brandId = $this->request->getPost('brandId');
$priceId = $this->request->getPost('priceId');
$qb = $this->entityManager->createQueryBuilder();
$mayor_a = 0;
$menor_a = 1000000000;
switch($priceId) {
case 1: {
$mayor_a = 0;
$menor_a = 999.99;
break;
}
case 2: {
$mayor_a = 1000;
$menor_a = 4999.99;
break;
}
case 3: {
$mayor_a = 5000;
$menor_a = 9999.99;
break;
}
case 4: {
$mayor_a = 10000;
$menor_a = 49999.99;
break;
}
case 5: {
$mayor_a = 50000;
$menor_a = 1000000000;
break;
}
}
$query = $this->entityManager->createQuery('SELECT * FROM pm_producto');
$products = $query->execute();
$view = new JsonModel();
// Set data to be used in the view
// $view->setVariable('productos', $productos);
$view->setVariable('is_xmlhttprequest', true);
$view->setVariable('categoryId', $categoryId);
$view->setVariable('brandId', $brandId);
$view->setVariable('mayor_a', $mayor_a);
$view->setVariable('menor_a', $menor_a);
$view->setVariable('products', $products);
/**
* Tell the renderer not to show the layout
* by setting setTerminal to true
*/
$view->setTerminal(true);
return $view;
}
public function getProductoAction()
{
// Checks if this is a Javascript request
$xmlHttpRequst = $this->getRequest()->isXmlHttpRequest();
if (! $xmlHttpRequst) {
die('Bad request');
}
$productId = $this->request->getPost('productId');
//$product = $this->entityManager->getRepository(Product::class)->findOneById($productId);
$view = new JsonModel();
// Set data to be used in the view
$product = json_encode(
'[{"id":"1","avatarUrl":"https://hiset.ets.org/rsc/img/icons/icon-tt-checklist.svg","nombre":"Hola soy prueba","descripcion":"Hola soy una descripcion de equipo medico"}]'
);
$view->setVariable('product', $product);
/**
* Tell the renderer not to show the layout
* by setting setTerminal to true
*/
$view->setTerminal(true);
return $view;
}
public function searchAction()
{
// Checks if this is a Javascript request
$xmlHttpRequst = $this->getRequest()->isXmlHttpRequest();
if (! $xmlHttpRequst) {
die('Bad request');
}
$categoryId = $this->request->getPost('categoryId');
$brandId = $this->request->getPost('brandId');
$priceId = $this->request->getPost('priceId');
$query = $this->entityManager->createQuery(
'SELECT * FROM pm_producto u WHERE u.'
);
$products = $query->execute();
$view = new JsonModel();
// Set data to be used in the view
$view->setVariable('products', $products);
/**
* Tell the renderer not to show the layout
* by setting setTerminal to true
*/
$view->setTerminal(true);
return $view;
}
public function cartAction()
{
return new ViewModel();
}
public function checkoutAction()
{
return new ViewModel();
}
public function payAction()
{
return new ViewModel();
}
public function confirmAction()
{
return new ViewModel();
}
public function successfulAction()
{
$mail = new Mail\Message();
$mail->setBody($email->getValue('message'));
$mail->setFrom($email->getValue('email'), $email->getValue('personal'));
$mail->addTo($this->reciverAddress, $this->reciverName);
$mail->setSubject($email->getValue('subject'));
$transport = new Mail\Transport\Sendmail();
$transport->send($mail);
return new ViewModel();
}
public function unsuccessfulAction()
{
return new ViewModel();
}
}
local.php
<?php
/**
* Local Configuration Override
*
* This configuration override file is for overriding environment-specific and
* security-sensitive configuration information. Copy this file without the
* .dist extension at the end and populate values as needed.
*
* @NOTE: This file is ignored from Git by default with the .gitignore included
* in ZendSkeletonApplication. This is a good practice, as it prevents sensitive
* credentials from accidentally being committed into version control.
*/
use Doctrine\DBAL\Driver\PDOMySql\Driver as PDOMySqlDriver;
return [
'doctrine' => [
'connection' => [
'orm_default' => [
'driverClass' => PDOMySqlDriver::class,
'params' => [
'host' => '127.0.0.1',
'user' => 'test',
'password' => 'test',
'dbname' => 'test',
]
],
],
],
];
modules.config.php
<?php
/**
* @link http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* List of enabled modules for this application.
*
* This should be an array of module namespaces used in the application.
*/
return [
'DoctrineModule',
'DoctrineORMModule',
'Zend\Paginator',
'Zend\Mail',
'Zend\I18n',
'Zend\InputFilter',
'Zend\Filter',
'Zend\Hydrator',
'Zend\Session',
'Zend\Mvc\Plugin\Prg',
'Zend\Mvc\Plugin\Identity',
'Zend\Mvc\Plugin\FlashMessenger',
'Zend\Mvc\Plugin\FilePrg',
'Zend\Form',
'Zend\Cache',
'Zend\Router',
'Zend\Validator',
'Application'
];
UPDATE #1
Entity/Categoria `
use Doctrine\ORM\Mapping as ORM;
/** * This class represents a registered user. * @ORM\Entity() * @ORM\Table(name="pm_categoria") */ class Categoria {
/**
* @ORM\Id
* @ORM\Column(name="ca_id")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(name="ca_created")
*/
protected $createdAt;
/**
* @ORM\Column(name="ca_modified")
*/
protected $modifiedAt;
/**
* @ORM\Column(name="ca_name")
*/
protected $name;
/**
* @ORM\Column(name="ca_description")
*/
protected $description;
/**
* @ORM\Column(name="ca_avatar_thumb_file_id")
*/
protected $avatarUrl;
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getCreatedAt()
{
return $this->createdAt;
}
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
}
public function getModifiedAt()
{
return $this->modifiedAt;
}
public function setModifiedAt($modifiedAt)
{
$this->modifiedAt = $modifiedAt;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getDescription()
{
return $this->description;
}
public function setDescription($description)
{
$this->description = $description;
}
public function getAvatarUrl()
{
return $this->avatarUrl;
}
public function setAvatarUrl($avatarUrl)
{
$this->avatarUrl = $avatarUrl;
}
}`
After executing vendor/bin/doctrine-module orm:schema-tool:update --dump-sql
ALTER TABLE pm_producto DROP FOREIGN KEY FK_ID_CATEGORY;
ALTER TABLE pm_producto DROP FOREIGN KEY FK_ID_MARCA;
DROP INDEX FK_ID_CATEGORY ON pm_producto;
DROP INDEX FK_ID_MARCA ON pm_producto;
ALTER TABLE pm_producto CHANGE pd_id pd_id VARCHAR(255) NOT NULL, CHANGE pd_id_categoria pd_id_categoria VARCHAR(255) NOT NULL, CHANGE pd_id_marca pd_id_marca VARCHAR(255) NOT NULL, CHANGE pd_created pd_created VARCHAR(255) NOT NULL, CHANGE pd_modified pd_modified VARCHAR(255) NOT NULL, CHANGE pd_available pd_available VARCHAR(255) NOT NULL, CHANGE pd_name pd_name VARCHAR(255) NOT NULL, CHANGE pd_description pd_description VARCHAR(255) NOT NULL, CHANGE pd_price pd_price VARCHAR(255) NOT NULL, CHANGE pd_avatar_thumb_file_id pd_avatar_thumb_file_id VARCHAR(255) NOT NULL;
ALTER TABLE pm_categoria CHANGE ca_id ca_id VARCHAR(255) NOT NULL, CHANGE ca_created ca_created VARCHAR(255) NOT NULL, CHANGE ca_modified ca_modified VARCHAR(255) NOT NULL, CHANGE ca_name ca_name VARCHAR(255) NOT NULL, CHANGE ca_description ca_description VARCHAR(255) NOT NULL, CHANGE ca_avatar_thumb_file_id ca_avatar_thumb_file_id VARCHAR(255) NOT NULL;
ALTER TABLE pm_detalle_factura DROP FOREIGN KEY FK_ID_PRODUCTO;
DROP INDEX FK_ID_PRODUCTO ON pm_detalle_factura;
ALTER TABLE pm_detalle_factura CHANGE df_id df_id VARCHAR(255) NOT NULL, CHANGE df_id_producto df_id_producto VARCHAR(255) NOT NULL, CHANGE df_created df_created VARCHAR(255) NOT NULL, CHANGE df_id_factura df_id_factura VARCHAR(255) NOT NULL, CHANGE df_cantidad df_cantidad VARCHAR(255) NOT NULL;
ALTER TABLE pm_marca CHANGE mr_id mr_id VARCHAR(255) NOT NULL, CHANGE mr_created mr_created VARCHAR(255) NOT NULL, CHANGE mr_name mr_name VARCHAR(255) NOT NULL;
ALTER TABLE pm_factura CHANGE fa_id fa_id VARCHAR(255) NOT NULL, CHANGE fa_created fa_created VARCHAR(255) NOT NULL, CHANGE fa_name fa_name VARCHAR(255) NOT NULL, CHANGE fa_nit fa_nit VARCHAR(255) NOT NULL, CHANGE fa_total fa_total VARCHAR(255) NOT NULL, CHANGE fa_paid fa_paid VARCHAR(255) NOT NULL;
UPDATE #2
I make it worked using createQueryBuilder
like this:
$qb = $this->entityManager->createQueryBuilder()
->select('s')
->from('Application\Entity\Marca', 's');
$obj = $qb->getQuery()->getArrayResult();
来源:https://stackoverflow.com/questions/47813604/zendframework-3-cant-get-entitymanager-on-application-module