我跟着this SO answer建立了我的DBAL连接作为服务。
我有以下配置:
在我的服务类文件" Doctrine.php"中,我有
<?php
namespace Acme\BookBundle\Services;
use Doctrine\Common\ClassLoader;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DriverManager;
class Doctrine
{
// Just rename __construct to create and make it static
static function create(){
$doctrineLoader = new ClassLoader('Doctrine');
$doctrineLoader->register();
$doctrineConfig = new Configuration();
$doctrineParams = [
'driver' => 'pdo_mysql',
'dbname' => 'book_enterprise_hub',
'host' => 'localhost',
'user' => 'root',
'password' => '',
];
return DriverManager::getConnection($doctrineParams, $doctrineConfig);
}
}
?>
在我的services.yml中,我有以下内容:
parameters:
dbal_connection: book_enterprise_hub
services:
doctrine:
class: Doctrine\DBAL\Connection
factory_class: 'Acme\BookBundle\Services\Doctrine'
factory_method: 'create'
在我的CompanyController.php中,我有以下代码,
<?php
use Acme\BookBundle\Services\Doctrine;
class CompanyController extends Controller
{
public function createAction()
{
$con = $this->get('doctrine');
$sqlQuery = "CREATE TABLE book_info (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, label TEXT, created_on DATETIME) ENGINE = INNODB";
$stmt = $con->prepare($sqlQuery);
$stmt->execute();
}
}
调用此行时 $ con&gt; prepare($ sqlQuery),
我收到以下错误,
尝试调用方法&#34;准备&#34; on class&#34; Doctrine \ Bundle \ DoctrineBundle \ Registry&#34;在C:\ wamp \ www \ symfony \ src \ Acme \ BookBundle \ Controller \ CompanyController.php
实际上,我使用工厂方法获取DBAL连接作为服务,但一直收到此错误。我可以在service.yml中编写参数,如上所述,或者我应该只在parameters.yml中写入?我究竟做错了什么?
答案 0 :(得分:2)
您链接的问题OP不使用Symfony2 Framework,他问如何使用Symfony配置组件设置Doctrine服务。
当您使用Symfony2时,您不需要执行任何操作,您可以这样做:
<?php
use Acme\BookBundle\Services\Doctrine;
class CompanyController extends Controller
{
public function createAction()
{
$con = $this->get('doctrine.dbal.default_connection');
$sqlQuery = "CREATE TABLE book_info (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, label TEXT, created_on DATETIME) ENGINE = INNODB";
$stmt = $con->prepare($sqlQuery);
$stmt->execute();
}
}
至于错误。抛出它是因为已经在Symfony中注册了一个名为doctrine
的服务,默认情况下它会解析为ManagerRegistry的实例。
那就是说,我不认为直接在控制器中使用连接是个好主意。
答案 1 :(得分:1)
您不必将教条配置为Symfony中的服务。它已作为服务提供,可以从控制器中的服务容器中检索:$this->getDoctrine()
或$this->get('some-service-id')
。您可以通过运行以下控制台命令来查看可用的服务及其相应的ID:
php app/console container:debug
您还可以将--show-private
选项添加到该命令以查看私有服务。一般来说,我认为最常见的学说服务将是学习实体管理器(doctrine.orm.entity_manager
),您可以使用它来存储/检索/删除数据库中的对象,以及用于查询数据的实体存储库,您可以设置作为单独注入其他服务的服务。
如果您只是尝试为应用程序构建表(即实体),则不需要/不应该在控制器中运行直接SQL查询。你应该做的是:
1)在捆绑包的Entity目录中创建您的学说Entity
类。例如:
// src/Acme/BookBundle/Entity/BookInfo.php
namespace Acme\BookBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="book_info")
*/
class BookInfo
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
...
}
2)运行php app/console doctrine:schema:update --force
控制台命令。这将指示doctrine在您为项目设置的数据库中创建实体表(连接信息应在app/config/parameters.yml
中)。
例如,要在数据库中存储BookInfo对象 $ myBookInfo ,就像在控制器中执行此操作一样简单:
...
$em = $this->getDoctrine()->getManager();
$em->persist($myBookInfo);
$em->flush;
...
当然,这是一个非常基本的例子,只是为了帮助您理解。
阅读Databases and Doctrine in Symfony了解更多详情。
答案 2 :(得分:1)
最后,我在symfony doc中非常仔细地阅读了服务容器,并使用了另一篇文章中某人给出的答案,并得到了以下配置为我工作:
在我的 services.yml 中,
parameters:
dbal_connection: book_enterprise_hub
bookservice.class: Acme\BookBundle\Services\BookService
services:
bookservice:
class: %bookservice.class%
**注意,我没有在这里传递参数,因为当它通过时,它抛出了这个错误“你已经请求了一个不存在的服务”doctrine.dbal.book_enterprise_hub“,所以,我通过了这个数据库信息在 bookservice __construct方法中。“。
在我的服务档案 BookService.php ,
中<?php
namespace Acme\BookBundle\Services;
//1st method (not working)
//use Doctrine\DBAL\Connection;
//second method
use Doctrine\Common\ClassLoader;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DriverManager;
class BookService
{
private $connection;
//1st method (not working)
// public function __construct(Connection $connection) {
// $this->connection = $connection;
// }
//second method
public function __construct() {
$doctrineLoader = new ClassLoader('BookService');
$doctrineLoader->register();
$doctrineConfig = new Configuration();
$doctrineParams = array(
'driver' => 'pdo_mysql',
'dbname' => 'book_enterprise_hub',
'host' => 'localhost',
'user' => 'root',
'password' => '',
);
$this->connection = DriverManager::getConnection($doctrineParams, $doctrineConfig);
}
public function createTable($tableName){
$sqlQuery = "CREATE TABLE ".$tableName." (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, label TEXT, created_on DATETIME) ENGINE = INNODB";
$stmt = $this->connection->prepare($sqlQuery);
if($stmt->execute())
{
return true;
}
}
}
在我的 BookController.php 中,我可以像这样的服务访问DBAL,
<?php
use Acme\BookBundle\Services\BookService;
class BookController extends Controller
{
/**
* Creates a new Book entity.
*
*/
public function createAction()
{
$tableName = $form->get('entityId')->getData();
$obj = $this->get('bookservice');
if($obj->createTable($tableName) == true){
// some code.
}
}
}
使用此配置,“您已请求不存在的服务.500内部服务器错误 - ServiceNotFoundException ”已解决。