【学习笔记】基于Composer创建MVC框架(三)—— doctrine使用

参考资料: https://lvwenhan.com/php/409.html

构建自己框架的下一步是集成ORM,参考文章里面作者使用的是Laravel的 illuminate/database 作为 ORM 包,我这里选择 doctrine/orm,symfony也集成了这个。

集成 doctrine/orm 到我们的 MFFC 框架的前提是先学会使用这个ORM。这篇文章纯粹记录如何使用doctrine/orm,并且都是在命令行下调试

官方文档:

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/tutorials/getting-started.html


安装并创建entity:
  1. 创建目录doctrine2-tutorial

  2. 创建composer.json文件,使用中国镜像,并且使用psr-0标准自动加载类库。

{
	"require": {
		"doctrine/orm": "v2.5.6"
	},
	"repositories": {
	    "packagist": {
	        "type": "composer",
	        "url": "https://packagist.phpcomposer.com"
	    }	
	},
        "autoload": {
            "psr-0": {"": "src/"}
        }
}

 3. 命令行进入到 doctrine2-tutorial,并且执行

composer install

 4. 安装成功之后,创建文件 bootstrap.php

<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

require_once "./vendor/autoload.php";

// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode);
// or if you prefer yaml or XML
//$config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
//$config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);

// database configuration parameters
$conn = array(
    'driver' => 'pdo_mysql',    
    'user'     => 'root',    
    'password' => 'password',    
    'dbname'   => 'foo',
);

// obtaining the entity manager
$entityManager = EntityManager::create($conn, $config);

我这里使用了pdo_mysql,所以要开启php的pdo_mysql扩展。也可以使用官方文档里面使用的pdo_sqllite数据库驱动,

// database configuration parameters
$conn = array(
    'driver' => 'pdo_sqlite',    
    'path' => __DIR__ . '/db.sqlite',
);

 5. 因为我们使用的命令行工具,所以需要创建文件cli-config.php

<?php
// cli-config.php
require_once "bootstrap.php";
return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($entityManager);

 6. 创建测试数据库foo

 7. 创建 product entity 作为测试,通过 product entity 对应数据表 products。步骤如下:

  • 创建文件夹 doctrine2-tutorial\src

  • 创建文件 doctrine2-tutorial\src\Product.php

<?php
// src/Product.php
/**
 * @Entity @Table(name="products")
 **/
class Product
{
    /** @Id @Column(type="integer") @GeneratedValue **/
    protected $id;
    /** @Column(type="string") **/
    protected $name;

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
            $this->name = $name;
    }
}

说明一下

@Entity @Table(name="products")

指定entity对应的数据表。

@Id @Column(type="integer") @GeneratedValue **/
    protected $id;

指定了entity的身份,也就是表的主键,如果多个字段作为主键的话,就应该都标识@Id,如下(这个定义没什么意义的,只是举例说明):

@Id @Column(type="integer")  **/
protected $id;@Id @Column(type="integer")  **/
protected $pid;

 8. 一切准备就绪之后,命令行的方式进入到项目根目录doctrine2-tutorial,执行命令

vendor\bin\doctrine orm:schema-tool:create

这里说明一下,官方文档里面介绍使用的命令是:

vendor/bin/doctrine orm:schema-tool:create

因为我们是在windows下面测试,所以需要使用反斜杠。

经过以上步骤,没什么意外的话,程序会帮我们在foo数据库里面创建表 products。这里要注意的是,在生产环境下,我们不使用第8步的命令。

另外,也可以使用xml或者yml的方式定义entity,如果使用yml文件的方式的话,还需要添加yaml依赖到composer.json,如下:

"symfony/yaml": "*"

使用product entity
  1. 插入数据到 products 表。创建文件doctrine2-tutorial\create_product.php

<?php
// create_product.php
require_once "bootstrap.php";
$newProductName = $argv[1];
$product = new Product();
$product->setName($newProductName);
$entityManager->persist($product);
$entityManager->flush();

echo "Created Product with ID " . $product->getId() . "\n";

命令行执行

php create_product.php ORM
php create_product.php DBAL

这两条命令会插入两条数据到products表,在create_product.php文件中的$argv[1]将会获取到命令行中的第二个参数,就是上面个的 ORM 和 DBAL,其中$argv[0]表示第一个参数,所以将会是命令行里面的脚本名称,也就是create_product.php。

如果没有意外的话,程序将会在 products 数据表里面插入两条数据

id      name
1	ORM
2	DBAL

 2. 查询数据。创建文件doctrine2-tutorial\show_product.php

<?php
// show_product.php <id>
require_once "bootstrap.php";
$ids = $argv[1];
$product = $entityManager->find('Product', $ids);
if ($product === null) {
    echo "No product found.\n";
    exit(1);
}

echo sprintf("-%s\n", $product->getName());

命令行执行

php show_product.php 1

 3. 更新数据。创建文件doctrine2-tutorial\show_product.php

<?php
// update_product.php <id> <new-name>
require_once "bootstrap.php";$id = $argv[1];
$newName = $argv[2];
$product = $entityManager->find('Product', $id);
if ($product === null) {
    echo "Product $id does not exist.\n";
    exit(1);
}
$product->setName($newName);
$entityManager->flush();

命令行执行

php update_product.php 1 new-ORM

没意外的话,数据表 products 里面id为1的数据的name字段将会更新为 new-ORM。

关键资料:

entity定义里面所有能使用的Annotations Reference

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#reference