ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
Doctrine 2
Who am I?
§£§Ñ§Ý§Ö§â§Ú§Û §²§Ñ§Ò§Ú§Ö§Ó§ã§Ü§Ú§Û
Team lead §Ó§Ö§Ò-§ã§ä§å§Õ§Ú§Ú stfalcon.com
§¡§Ü§ä§Ú§Ó§ß§í§Û §â§Ñ§Ù§â§Ñ§Ò§à§ä§é§Ú§Ü Open Source
§Õ§Ó§Ú§Ø§Ü§Ñ ZFEngine (ZF + Doctrine)
§¢§à§Ý§Ö§Ö 4 §Ý§Ö§ä §à§á§í§ä§Ñ §â§Ñ§Ò§à§ä§í §ã PHP
§±§à§é§Ö§Þ§å?
Doctrine 2
§¢§Ú§Ò§Ý§Ú§à§ä§Ö§Ü§Ú
¡ª Common
¡ª DBAL (§Ó§Ü§Ý§ð§é§Ñ§Ö§ä Common)
¡ª ORM (§Ó§Ü§Ý§ð§é§Ñ§Ö§ä DBAL+Common)
¡ª Migrations (§é§Ñ§ã§ä§î DBAL)
¡ª Object Document Mapper:
MongoDB
CouchDB
github.com/doctrine
Entities
¡ª §­§Ö§Ô§Ü§Ñ§ñ §Þ§à§Õ§Ö§Ý§î (§ã§Ñ§Þ§í§Û §á§â§à§ã§ä§à§Û PHP §Ü§Ý§Ñ§ã§ã)
¡ª §¯§Ö §ß§å§Ø§ß§à §ß§Ñ§ã§Ý§Ö§Õ§à§Ó§Ñ§ß§Ú§Ö §à§ä §Ò§Ñ§Ù§à§Ó§à§Ô§à §Ü§Ý§Ñ§ã§ã§Ñ
¡ª §¦§ã§ä§î §Ó§à§Ù§Þ§à§Ø§ß§à§ã§ä§î §ß§Ñ§ã§Ý§Ö§Õ§à§Ó§Ñ§ä§î §Þ§à§Õ§Ö§Ý§î §à§ä
§ã§Ó§à§Ú§ç §Ò§Ñ§Ù§à§Ó§í§ç §Ü§Ý§Ñ§ã§ã§à§Ó
¡ª §¬§à§ß§ã§ä§â§å§Ü§ä§à§â §Þ§à§Õ§Ö§Ý§Ú §Þ§à§Ø§ß§à §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ä§î
§Õ§Ý§ñ §ã§Ó§à§Ú§ç §ß§å§Ø§Õ
¡ª §¥§Ñ§ß§ß§í§Ö §ç§â§Ñ§ß§ñ§ä§ã§ñ §ß§Ö§á§à§ã§â§Ö§Õ§ã§ä§Ó§Ö§ß§ß§à §Ó
§ã§Ó§à§Û§ã§ä§Ó§Ñ§ç §à§Ò§ì§Ö§Ü§ä§Ñ
§±§â§Ú§Þ§Ö§â §Þ§à§Õ§Ö§Ý§Ú
namespace Entities;
class User
{
private $id;
private $name;
public function getId() { return $this->id; }
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}
namespace Entities;
class User
{
private $id;
private $name;
public function getId() { return $this->id; }
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}
EntityManager
EntityManager §ñ§Ó§Ý§ñ§Ö§ä§ã§ñ §è§Ö§ß§ä§â§Ñ§Ý§î§ß§à§Û
§ä§à§é§Ü§à§Û §Õ§à§ã§ä§å§á§Ñ §Ü §æ§å§ß§Ü§è§Ú§ñ§Þ ORM
¡ª §µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §à§Ò§ß§à§Ó§Ý§Ö§ß§Ú§Ö§Þ §ã§å§ë§ß§à§ã§ä§Ö§Û
¡ª §¥§à§ã§ä§å§á §Ü §â§Ö§á§à§Ù§Ú§ä§à§â§Ú§ñ§Þ §ã§å§ë§ß§à§ã§ä§Ö§Û
¡ª §ª§ã§á§à§Ý§î§Ù§å§Ö§ä§ã§ñ §á§Ñ§ä§ä§Ö§â§ß UnitOfWork
ZF2 + D2
protected function _initAutoload()
{
$loader = new ZendLoaderStandardAutoloader();
$loader->registerNamespace('Doctrine', '/path/to/Doctrine');
$loader->registerNamespace('Symfony', '/path/to/Symfony');
$loader->register();
}
protected function _initAutoload()
{
$loader = new ZendLoaderStandardAutoloader();
$loader->registerNamespace('Doctrine', '/path/to/Doctrine');
$loader->registerNamespace('Symfony', '/path/to/Symfony');
$loader->register();
}
§¥§à§Ò§Ñ§Ó§Ý§ñ§Ö§Þ §Ñ§Ó§ä§à§Ù§Ñ§Ô§â§å§Ù§Ü§å §Ó Bootstrap
§¯§Ñ§ã§ä§â§à§Û§Ü§Ñ Doctrine 2
./application/configs/application.xml
<!-- production -->
<doctrine>
<connection><!-- user, password, database, etc --></connection>
<paths>
<entities>path/to/entities</entities>
<proxies>path/to/proxies</proxies>
</paths>
<proxiesNamespace value="ApplicationModelProxies" />
<autogenerateProxyClasses value="0" />
<cacheAdapter value="DoctrineCommonCacheApcCache" />
</doctrine>
<!-- development -->
...
<autogenerateProxyClasses value="1" />
<cacheAdapter value="DoctrineCommonCacheArrayCache" />
¡­
<!-- production -->
<doctrine>
<connection><!-- user, password, database, etc --></connection>
<paths>
<entities>path/to/entities</entities>
<proxies>path/to/proxies</proxies>
</paths>
<proxiesNamespace value="ApplicationModelProxies" />
<autogenerateProxyClasses value="0" />
<cacheAdapter value="DoctrineCommonCacheApcCache" />
</doctrine>
<!-- development -->
...
<autogenerateProxyClasses value="1" />
<cacheAdapter value="DoctrineCommonCacheArrayCache" />
¡­
§±§à§Õ§Ü§Ý§ð§é§Ö§ß§Ú§Ö EntityManager
protected function _initEntityManager() {
if (is_null($this->_em)) {
$options = $this->getOption('doctrine');
$cache = new $options['cacheAdapter'];
$config = new Configuration();
$driverImpl = $config
->newDefaultAnnotationDriver($options['paths']['entities']);
$config->setMetadataCacheImpl($cache);
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCacheImpl($cache);
$config->setProxyNamespace($options['proxiesNamespace']);
$config->setProxyDir($options['paths']['proxies']);
$config->setAutoGenerateProxyClasses(
$options['autogenerateProxyClasses']
);
$this->_em =
EntityManager::create($options['connection'], $config);
}
return $this->_em;
}
protected function _initEntityManager() {
if (is_null($this->_em)) {
$options = $this->getOption('doctrine');
$cache = new $options['cacheAdapter'];
$config = new Configuration();
$driverImpl = $config
->newDefaultAnnotationDriver($options['paths']['entities']);
$config->setMetadataCacheImpl($cache);
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCacheImpl($cache);
$config->setProxyNamespace($options['proxiesNamespace']);
$config->setProxyDir($options['paths']['proxies']);
$config->setAutoGenerateProxyClasses(
$options['autogenerateProxyClasses']
);
$this->_em =
EntityManager::create($options['connection'], $config);
}
return $this->_em;
}
Mapping
Basic Mapping
¡ª Docblock Annotations
¡ª XML
¡ª YAML
¡ª PHP
Association Mapping
¡ª One-To-One & Many-To-Many:
¡ª Unidirectional
¡ª Bidirectional
¡ª Self-referencing
¡ª Many-To-One, Unidirectional
¡ª One-To-Many:
¡ª Unidirectional with Join Table
¡ª Bidirectional
¡ª Self-referencing
Inheritance Mapping
¡ª Mapped Superclasses
¡ª Single Table Inheritance
¡ª Class Table Inheritance
Mapping
...
/**
* @ManyToOne(targetEntity="Address", inversedBy="users")
* @JoinColumn(name="address_id", referencedColumnName="id")
*/
private $address;
...
...
/**
* @ManyToOne(targetEntity="Address", inversedBy="users")
* @JoinColumn(name="address_id", referencedColumnName="id")
*/
private $address;
...
...
/** @OneToMany(targetEntity="User", mappedBy="address") */
private $user;
...
...
/** @OneToMany(targetEntity="User", mappedBy="address") */
private $user;
...
Entities/User
Entitites/Address
Console
Console
...
$em = $application->getBootstrap()->getResource('EntityManager');
...
$helpers = array(
'db' => new DBALHelperConnectionHelper($em->getConnection()),
'em' => new ORMHelperEntityManagerHelper($em),
'dialog' => new SymfonyComponentConsoleHelperDialogHelper(),
);
...
$cli = new SymfonyComponentConsoleApplication(
'Doctrine Command Line Interface', DoctrineCommonVersion::VERSION);
$cli->setCatchExceptions(true);
...
$cli->addCommands(array(
new DBALCommandRunSqlCommand(),
new ORMCommandValidateSchemaCommand(),
new MigrationsCommandVersionCommand()
));
$cli->run();
...
$em = $application->getBootstrap()->getResource('EntityManager');
...
$helpers = array(
'db' => new DBALHelperConnectionHelper($em->getConnection()),
'em' => new ORMHelperEntityManagerHelper($em),
'dialog' => new SymfonyComponentConsoleHelperDialogHelper(),
);
...
$cli = new SymfonyComponentConsoleApplication(
'Doctrine Command Line Interface', DoctrineCommonVersion::VERSION);
$cli->setCatchExceptions(true);
...
$cli->addCommands(array(
new DBALCommandRunSqlCommand(),
new ORMCommandValidateSchemaCommand(),
new MigrationsCommandVersionCommand()
));
$cli->run();
Console
$ ./doctrine
Doctrine Command Line Interface version 2.0.0RC3-DEV
Usage:
[options] command [arguments]
dbal
:import
:run-sql
orm
:convert-d1-schema
:convert-mapping
:generate-proxies
:generate-repositories
:run-dql
:validate-schema
orm:clear-cache
:metadata
:query
:result
$ ./doctrine
Doctrine Command Line Interface version 2.0.0RC3-DEV
Usage:
[options] command [arguments]
dbal
:import
:run-sql
orm
:convert-d1-schema
:convert-mapping
:generate-proxies
:generate-repositories
:run-dql
:validate-schema
orm:clear-cache
:metadata
:query
:result
Console: ORM
$ ./doctrine orm:ensure-production-settings
Proxy Classes are always regenerating.
$ ./doctrine orm:ensure-production-settings
SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost'
$ ./doctrine orm:ensure-production-settings
Environment is correctly configured for production.
$ ./doctrine orm:ensure-production-settings
Proxy Classes are always regenerating.
$ ./doctrine orm:ensure-production-settings
SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost'
$ ./doctrine orm:ensure-production-settings
Environment is correctly configured for production.
§±§â§à§Ó§Ö§â§Ü§Ñ §Ü§à§â§â§Ö§Ü§ä§ß§à§ã§ä§Ú §ß§Ñ§ã§ä§â§à§Ö§Ü
§Õ§Ý§ñ production
Console: ORM
§£§Ñ§Ý§Ú§Õ§Ñ§è§Ú§ñ §Þ§à§Õ§Ö§Ý§Ú
$ ./doctrine orm:validate-schema
[Mapping] FAIL - The entity-class 'EntitiesAddress' mapping is invalid:
* The field EntitiesAddress#user is on the inverse side of a
bi-directional Relationship, but the specified mappedBy association
on the target-entity EntitiesUser#address does not contain the
required 'inversedBy' attribute.
[Database] FAIL - The database schema is not in sync with the
current mapping file.
$ ./doctrine orm:validate-schema
[Mapping] FAIL - The entity-class 'EntitiesAddress' mapping is invalid:
* The field EntitiesAddress#user is on the inverse side of a
bi-directional Relationship, but the specified mappedBy association
on the target-entity EntitiesUser#address does not contain the
required 'inversedBy' attribute.
[Database] FAIL - The database schema is not in sync with the
current mapping file.
Migrations
Migrations
§¹§ä§à §ß§å§Ø§ß§à:
¡ª §ã§ä§Ñ§ß§Õ§Ñ§â§ä§ß§í§Û §ã§Ü§â§Ú§á§ä §Õ§Ý§ñ §á§à§Õ§Ü§Ý§ð§é§Ö§ß§Ú§ñ §Ü§à§ß§ã§à§Ý§Ú
¡ª §Ó §á§Ñ§á§Ü§å §ã §ã§Ü§â§Ú§á§ä§à§Þ §Õ§à§Ò§Ñ§Ó§Ú§ä§î migrations.xml (§Ú§Ý§Ú yaml)
<doctrine-migrations>
<name>Doctrine Migrations</name>
<migrations-namespace>
DoctrineMigrations
</migrations-namespace>
<table name="migration_versions" />
<migrations-directory>/path/to/migrations/</migrations-directory>
</doctrine-migrations>
<doctrine-migrations>
<name>Doctrine Migrations</name>
<migrations-namespace>
DoctrineMigrations
</migrations-namespace>
<table name="migration_versions" />
<migrations-directory>/path/to/migrations/</migrations-directory>
</doctrine-migrations>
Migrations
§¥§à§ã§ä§å§á§ß§í§Ö §Ü§à§Þ§Ñ§ß§Õ§í
$ ./doctrine
...
migrations
:diff :generate :status
:execute :migrate :version
...
$ ./doctrine
...
migrations
:diff :generate :status
:execute :migrate :version
...
Migrations
§¶§Ú§Ü§ã§Ú§â§å§Ö§Þ §Ú§Ù§Þ§Ö§ß§Ö§ß§Ú§ñ §Ó §Þ§Ú§Ô§â§Ñ§è§Ú§Ú
$ ./doctrine migrations:diff
Generated new migration class
to "path/to/migrations/Version20101124201328.php" from schema differences.
$ ./doctrine migrations:diff
Generated new migration class
to "path/to/migrations/Version20101124201328.php" from schema differences.
namespace DoctrineMigrations;
class Version20101124201328 extends AbstractMigration
{
public function up(Schema $schema) {
$this->_addSql('CREATE TABLE users (...) ENGINE = InnoDB');
}
public function down(Schema $schema) {
$this->_addSql('DROP TABLE users');
}
}
namespace DoctrineMigrations;
class Version20101124201328 extends AbstractMigration
{
public function up(Schema $schema) {
$this->_addSql('CREATE TABLE users (...) ENGINE = InnoDB');
}
public function down(Schema $schema) {
$this->_addSql('DROP TABLE users');
}
}
Migrations
§¯§Ñ§Ü§Ñ§ä§í§Ó§Ñ§ß§Ú§Ö §Þ§Ú§Ô§â§Ñ§è§Ú§Ú
$ ./doctrine migrations:migrate --dry-run
Executing dry run of migration up to 20101124201328 from 0
++ migrating 20101124201328
-> CREATE TABLE users ( ... ) ENGINE = InnoDB
++ migrated (0.01s)
------------------------
++ finished in 0.01
++ 1 migrations executed
++ 1 sql queries
$ ./doctrine migrations:migrate --dry-run
Executing dry run of migration up to 20101124201328 from 0
++ migrating 20101124201328
-> CREATE TABLE users ( ... ) ENGINE = InnoDB
++ migrated (0.01s)
------------------------
++ finished in 0.01
++ 1 migrations executed
++ 1 sql queries
Migrations
§¤§Ö§ß§Ö§â§Ú§â§å§Ö§Þ §Ù§Ñ§Ô§à§ä§à§Ó§Ü§å §Þ§Ú§Ô§â§Ñ§è§Ú§Ú
$ ./doctrine migrations:generate --editor-cmd=netbeans
Generated new migration class to "path/to/migrations/Version20101124201328.php"
$ ./doctrine migrations:generate --editor-cmd=netbeans
Generated new migration class to "path/to/migrations/Version20101124201328.php"
namespace DoctrineMigrations;
class Version20101124201328 extends AbstractMigration
{
public function up(Schema $schema) {
// $this->_addSql('CREATE TABLE users (...) ENGINE = InnoDB');
$table = $schema->createTable('users');
$table->addColumn('username', 'string');
}
public function down(Schema $schema) {
$schema->dropTable('users');
}
}
namespace DoctrineMigrations;
class Version20101124201328 extends AbstractMigration
{
public function up(Schema $schema) {
// $this->_addSql('CREATE TABLE users (...) ENGINE = InnoDB');
$table = $schema->createTable('users');
$table->addColumn('username', 'string');
}
public function down(Schema $schema) {
$schema->dropTable('users');
}
}
§ª§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö
§±§â§Ú§Þ§Ö§â §â§Ñ§Ò§à§ä§í §ã §Þ§à§Õ§Ö§Ý§ñ§Þ§Ú
$em = $this->getInvokeArg('bootstrap')
->getResource('EntityManager');
$address = new EntitiesAddress();
$address->setStreet('§¬§Ú§Ö§Ó§ã§Ü§Ñ§ñ, 1');
$user = new EntitiesUser();
$user->setName('§£§Ñ§ß§ñ');
$user->setAddress($address);
$em->persist($address);
$em->persist($user);
$em->flush();
$em = $this->getInvokeArg('bootstrap')
->getResource('EntityManager');
$address = new EntitiesAddress();
$address->setStreet('§¬§Ú§Ö§Ó§ã§Ü§Ñ§ñ, 1');
$user = new EntitiesUser();
$user->setName('§£§Ñ§ß§ñ');
$user->setAddress($address);
$em->persist($address);
$em->persist($user);
$em->flush();
§ª§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö
§±§â§Ú§Þ§Ö§â §â§Ñ§Ò§à§ä§í §ã §Þ§à§Õ§Ö§Ý§ñ§Þ§Ú
$user = $em->find('EntitiesUser', 1);
$user->getAddress();
// ¡ú object ProxiesEntitiesAddressProxy
$user->getName(); // §£§Ñ§ß§ñ
$user->setName('§±§Ö§ä§ñ');
$em->flush();
...
$user = $em->find('EntitiesUser', 1);
$user->getName(); // §±§Ö§ä§ñ
$user = $em->find('EntitiesUser', 1);
$user->getAddress();
// ¡ú object ProxiesEntitiesAddressProxy
$user->getName(); // §£§Ñ§ß§ñ
$user->setName('§±§Ö§ä§ñ');
$em->flush();
...
$user = $em->find('EntitiesUser', 1);
$user->getName(); // §±§Ö§ä§ñ
Doctrine Query Language
Doctrine 1
¡ª §¯§Ö §Ò§í§Ý§à §â§Ö§Ñ§Ý§î§ß§à§Ô§à §á§Ñ§â§ã§Ö§â§Ñ DQL
Doctrine 2
¡ª Abstract Syntax Tree
Behaviors
Behaviors
§¯§Ö§ä §Ú §ß§Ö §Ò§å§Õ§Ö§ä
§â§Ñ§ã§ê§Ú§â§Ö§ß§Ú§Û ?§Ú§Ù §Ü§à§â§à§Ò§Ü§Ú?
Events & Subscribers+
?
Events
namespace Entities;
/**
* @HasLifecycleCallbacks
*/
class User {
¡­
/** @PrePersist */
public function updateCreatedAt()
{
$this->createdAt = date('Y-m-d H:m:s');
}
}
namespace Entities;
/**
* @HasLifecycleCallbacks
*/
class User {
¡­
/** @PrePersist */
public function updateCreatedAt()
{
$this->createdAt = date('Y-m-d H:m:s');
}
}
Lifecycle Events
¡ª pre/postRemove
¡ª pre/postPersist
¡ª pre/postUpdate
¡ª postLoad
¡ª loadClassMetadata
¡ª onFlush
Event Listeners
§±§â§à§ã§ä§Ö§Û§ê§Ú§Û §á§à§Õ§á§Ú§ã§é§Ú§Ü §ß§Ñ §ã§à§Ò§í§ä§Ú§ñ
class MyEventSubscriber implements EventSubscriber
{
public function getSubscribedEvents() {
return array(
Events::preUpdate
);
}
public function preUpdate(PreUpdateEventArgs $eventArgs) {
if ($eventArgs->getEntity() instanceof User) {
if ($eventArgs->hasChangedField('name')) { /*§ß§Ñ§ê §Ü§à§Õ*/ }
}
}
}
$entityManager->getEventManager()
->addEventSubscriber(new MyEventSubscriber());
class MyEventSubscriber implements EventSubscriber
{
public function getSubscribedEvents() {
return array(
Events::preUpdate
);
}
public function preUpdate(PreUpdateEventArgs $eventArgs) {
if ($eventArgs->getEntity() instanceof User) {
if ($eventArgs->hasChangedField('name')) { /*§ß§Ñ§ê §Ü§à§Õ*/ }
}
}
}
$entityManager->getEventManager()
->addEventSubscriber(new MyEventSubscriber());
Behavioral Extensions
goo.gl/Mgnwg
(www.doctrine-project.org/blog/doctrine2-behavioral-extensions)
...
/**
* @gedmo:Timestampable(on="create")
* @Column(type="date")
*/
private $created;
/**
* @gedmo:Timestampable(on="update")
* @Column(type="datetime")
*/
private $updated;
...
...
/**
* @gedmo:Timestampable(on="create")
* @Column(type="date")
*/
private $created;
/**
* @gedmo:Timestampable(on="update")
* @Column(type="datetime")
*/
private $updated;
...
§²§Ö§á§Ý§Ú§Ü§Ñ§è§Ú§ñ
Doctrine 1
$connections = array(
'master' => 'mysql://root:@master/dbname',
'slave_1' => 'mysql://root:@slave1/dbname',
'slave_2' => 'mysql://root:@slave2/dbname',
);
foreach ($connections as $name => $dsn) {
Doctrine_Manager::connection($dsn, $name);
}
$connections = array(
'master' => 'mysql://root:@master/dbname',
'slave_1' => 'mysql://root:@slave1/dbname',
'slave_2' => 'mysql://root:@slave2/dbname',
);
foreach ($connections as $name => $dsn) {
Doctrine_Manager::connection($dsn, $name);
}
§²§Ö§á§Ý§Ú§Ü§Ñ§è§Ú§ñ
Doctrine 1
Doctrine 2
:(
$connections = array(
'master' => 'mysql://root:@master/dbname',
'slave_1' => 'mysql://root:@slave1/dbname',
'slave_2' => 'mysql://root:@slave2/dbname',
);
foreach ($connections as $name => $dsn) {
Doctrine_Manager::connection($dsn, $name);
}
$connections = array(
'master' => 'mysql://root:@master/dbname',
'slave_1' => 'mysql://root:@slave1/dbname',
'slave_2' => 'mysql://root:@slave2/dbname',
);
foreach ($connections as $name => $dsn) {
Doctrine_Manager::connection($dsn, $name);
}
§²§Ö§á§Ý§Ú§Ü§Ñ§è§Ú§ñ
§£ Doctrine 2 §Ó§ã§Ö §Õ§Ö§Û§ã§ä§Ó§Ú§ñ §ã §Þ§à§Õ§Ö§Ý§î§ð
§á§â§à§Ú§ã§ç§à§Õ§ñ§ä §é§Ö§â§Ö§Ù EntityManager
§©§ß§Ñ§é§Ú§ä §Þ§à§Ø§ß§à:
¡ª §ã§à§Ù§Õ§Ñ§ä§î §ß§Ö§ã§Ü§à§Ý§î§Ü§à EM §ß§Ñ §Ü§Ñ§Ø§Õ§à§Ö
§á§à§Õ§Ü§Ý§ð§é§Ö§ß§Ú§Ö;
¡ª §â§Ñ§ã§ê§Ú§â§Ú§ä§î §ã§ä§Ñ§ß§Õ§Ñ§â§ä§ß§í§Û EM §á§à§Õ§Õ§Ö§â§Ø§Ü§à§Û
§â§Ö§á§Ý§Ú§Ü§Ñ§è§Ú§Û;
§±§â§Ö§Õ§á§à§ã§Ý§Ö§Õ§ß§ñ§ñ
§ª§ã§ç§à§Õ§ß§í§Û §Ü§à§Õ §Þ§à§Ú§ç §ï§Ü§ã§á§Ö§â§Ú§Þ§Ö§ß§ä§à§Ó §ã ZF2 §Ú
Doctrine 2 §ã§Ü§à§â§à §á§à§ñ§Ó§Ú§ä§ã§ñ §ß§Ñ GitHub'e:
github.com/ftrrtf
§³§á§Ñ§ã§Ú§Ò§à §Ù§Ñ §Ó§ß§Ú§Þ§Ñ§ß§Ú§Ö!
§¦§ã§ä§î §Ó§à§á§â§à§ã§í?
§£§Ñ§Ý§Ö§â§Ú§Û §²§Ñ§Ò§Ú§Ö§Ó§ã§Ü§Ú§Û
mail@ftrrtf.com
twitter.com/ftrrtf
facebook.com/ftrrtf

More Related Content

What's hot (19)

Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
Pierre MARTIN
?
Future of HTTP in CakePHP
Future of HTTP in CakePHPFuture of HTTP in CakePHP
Future of HTTP in CakePHP
markstory
?
CakeFest 2013 keynote
CakeFest 2013 keynoteCakeFest 2013 keynote
CakeFest 2013 keynote
Jos¨¦ Lorenzo Rodr¨ªguez Urdaneta
?
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
ddiers
?
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
PrinceGuru MS
?
Lithium Best
Lithium Best Lithium Best
Lithium Best
Richard McIntyre
?
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
smueller_sandsmedia
?
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
Bastian Feder
?
Drupal Field API. Practical usage
Drupal Field API. Practical usageDrupal Field API. Practical usage
Drupal Field API. Practical usage
Pavel Makhrinsky
?
Advanced Querying with CakePHP 3
Advanced Querying with CakePHP 3Advanced Querying with CakePHP 3
Advanced Querying with CakePHP 3
Jos¨¦ Lorenzo Rodr¨ªguez Urdaneta
?
Drupal 8 migrate!
Drupal 8 migrate!Drupal 8 migrate!
Drupal 8 migrate!
Pavel Makhrinsky
?
Drupal Render API
Drupal Render APIDrupal Render API
Drupal Render API
Pavel Makhrinsky
?
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
G Woo
?
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
Bastian Feder
?
Field api.From d7 to d8
Field api.From d7 to d8Field api.From d7 to d8
Field api.From d7 to d8
Pavel Makhrinsky
?
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
Nate Abele
?
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
?
Current state-of-php
Current state-of-phpCurrent state-of-php
Current state-of-php
Richard McIntyre
?
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks
Damien Seguy
?

Viewers also liked (17)

§·§â§Ñ§ß§Ö§ß§Ú§Ö, §à§Ò§â§Ñ§Ò§à§ä§Ü§Ñ §Ú §à§ä§Õ§Ñ§é§Ñ §ã§ä§Ñ§ä§Ú§Ü§Ú §ã §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö§Þ \Zend\File. §°§á§í§ä §ã§à§è§Ú§Ñ§Ý...
§·§â§Ñ§ß§Ö§ß§Ú§Ö, §à§Ò§â§Ñ§Ò§à§ä§Ü§Ñ §Ú §à§ä§Õ§Ñ§é§Ñ §ã§ä§Ñ§ä§Ú§Ü§Ú §ã §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö§Þ \Zend\File. §°§á§í§ä §ã§à§è§Ú§Ñ§Ý...§·§â§Ñ§ß§Ö§ß§Ú§Ö, §à§Ò§â§Ñ§Ò§à§ä§Ü§Ñ §Ú §à§ä§Õ§Ñ§é§Ñ §ã§ä§Ñ§ä§Ú§Ü§Ú §ã §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö§Þ \Zend\File. §°§á§í§ä §ã§à§è§Ú§Ñ§Ý...
§·§â§Ñ§ß§Ö§ß§Ú§Ö, §à§Ò§â§Ñ§Ò§à§ä§Ü§Ñ §Ú §à§ä§Õ§Ñ§é§Ñ §ã§ä§Ñ§ä§Ú§Ü§Ú §ã §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö§Þ \Zend\File. §°§á§í§ä §ã§à§è§Ú§Ñ§Ý...
zfconfua
?
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö Scrum §Ú Kanban §Õ§Ý§ñ §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ú web-§á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö Scrum §Ú Kanban §Õ§Ý§ñ §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ú web-§á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö Scrum §Ú Kanban §Õ§Ý§ñ §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ú web-§á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö Scrum §Ú Kanban §Õ§Ý§ñ §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ú web-§á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û
Kirill Klimov
?
§±§â§Ö§Ú§Þ§å§ë§Ö§ã§ä§Ó§Ñ §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§ñ §á§à§Ý§ß§à§ä§Ö§Ü§ã§ä§à§Ó§à§Ô§à §á§à§Ú§ã§Ü§Ñ §Ó §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§Ñ§ç
§±§â§Ö§Ú§Þ§å§ë§Ö§ã§ä§Ó§Ñ §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§ñ §á§à§Ý§ß§à§ä§Ö§Ü§ã§ä§à§Ó§à§Ô§à §á§à§Ú§ã§Ü§Ñ §Ó §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§Ñ§ç§±§â§Ö§Ú§Þ§å§ë§Ö§ã§ä§Ó§Ñ §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§ñ §á§à§Ý§ß§à§ä§Ö§Ü§ã§ä§à§Ó§à§Ô§à §á§à§Ú§ã§Ü§Ñ §Ó §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§Ñ§ç
§±§â§Ö§Ú§Þ§å§ë§Ö§ã§ä§Ó§Ñ §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§ñ §á§à§Ý§ß§à§ä§Ö§Ü§ã§ä§à§Ó§à§Ô§à §á§à§Ú§ã§Ü§Ñ §Ó §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§Ñ§ç
Magecom Ukraine
?
§£§ã§Ö §Õ§à§â§à§Ô§Ú §Ó§Ö§Õ§å§ä §Ó Checkout
§£§ã§Ö §Õ§à§â§à§Ô§Ú §Ó§Ö§Õ§å§ä §Ó Checkout§£§ã§Ö §Õ§à§â§à§Ô§Ú §Ó§Ö§Õ§å§ä §Ó Checkout
§£§ã§Ö §Õ§à§â§à§Ô§Ú §Ó§Ö§Õ§å§ä §Ó Checkout
Magecom Ukraine
?
§¿§Ó§à§Ý§ð§è§Ú§ñ ZF: §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§Ñ, §ê§Ñ§Ò§Ý§à§ß§í, §â§Ö§æ§Ñ§Ü§ä§à§â§Ú§ß§Ô
§¿§Ó§à§Ý§ð§è§Ú§ñ ZF: §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§Ñ, §ê§Ñ§Ò§Ý§à§ß§í, §â§Ö§æ§Ñ§Ü§ä§à§â§Ú§ß§Ô§¿§Ó§à§Ý§ð§è§Ú§ñ ZF: §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§Ñ, §ê§Ñ§Ò§Ý§à§ß§í, §â§Ö§æ§Ñ§Ü§ä§à§â§Ú§ß§Ô
§¿§Ó§à§Ý§ð§è§Ú§ñ ZF: §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§Ñ, §ê§Ñ§Ò§Ý§à§ß§í, §â§Ö§æ§Ñ§Ü§ä§à§â§Ú§ß§Ô
zfconfua
?
§£§ã§ä§â§Ö§é§Ñ§Û§ä§Ö Zend Framework 2.0
§£§ã§ä§â§Ö§é§Ñ§Û§ä§Ö Zend Framework 2.0§£§ã§ä§â§Ö§é§Ñ§Û§ä§Ö Zend Framework 2.0
§£§ã§ä§â§Ö§é§Ñ§Û§ä§Ö Zend Framework 2.0
zfconfua
?
1000 §Þ§Ú§Ý§Ý§Ú§ã§Ö§Ü§å§ß§Õ §Ú§Ù §Ø§Ú§Ù§ß§Ú Magento
1000 §Þ§Ú§Ý§Ý§Ú§ã§Ö§Ü§å§ß§Õ §Ú§Ù §Ø§Ú§Ù§ß§Ú Magento1000 §Þ§Ú§Ý§Ý§Ú§ã§Ö§Ü§å§ß§Õ §Ú§Ù §Ø§Ú§Ù§ß§Ú Magento
1000 §Þ§Ú§Ý§Ý§Ú§ã§Ö§Ü§å§ß§Õ §Ú§Ù §Ø§Ú§Ù§ß§Ú Magento
Magecom Ukraine
?
§®§à§Ò§Ú§Ý§î§ß§í§Ö §Ü§Ý§Ú§Ö§ß§ä§í §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§à§Ó
§®§à§Ò§Ú§Ý§î§ß§í§Ö §Ü§Ý§Ú§Ö§ß§ä§í §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§à§Ó§®§à§Ò§Ú§Ý§î§ß§í§Ö §Ü§Ý§Ú§Ö§ß§ä§í §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§à§Ó
§®§à§Ò§Ú§Ý§î§ß§í§Ö §Ü§Ý§Ú§Ö§ß§ä§í §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§à§Ó
Magecom Ukraine
?
§²§Ö§Ñ§Ý§Ú§Ù§Ñ§è§Ú§ñ §ê§Ñ§Ò§Ý§à§ß§à§Ó §Ü§à§â§á§à§â§Ñ§ä§Ú§Ó§ß§í§ç §á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û §Ó Magento
§²§Ö§Ñ§Ý§Ú§Ù§Ñ§è§Ú§ñ §ê§Ñ§Ò§Ý§à§ß§à§Ó §Ü§à§â§á§à§â§Ñ§ä§Ú§Ó§ß§í§ç §á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û §Ó Magento§²§Ö§Ñ§Ý§Ú§Ù§Ñ§è§Ú§ñ §ê§Ñ§Ò§Ý§à§ß§à§Ó §Ü§à§â§á§à§â§Ñ§ä§Ú§Ó§ß§í§ç §á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û §Ó Magento
§²§Ö§Ñ§Ý§Ú§Ù§Ñ§è§Ú§ñ §ê§Ñ§Ò§Ý§à§ß§à§Ó §Ü§à§â§á§à§â§Ñ§ä§Ú§Ó§ß§í§ç §á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û §Ó Magento
Magecom Ukraine
?
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö §Ü§à§Þ§á§à§ß§Ö§ß§ä-§à§â§Ú§Ö§ß§ä§Ú§â§à§Ó§Ñ§ß§ß§à§Û §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§í §Õ§Ý§ñ §ß§Ñ§á§Ú§ã§Ñ§ß§Ú§ñ Magento Extens...
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö §Ü§à§Þ§á§à§ß§Ö§ß§ä-§à§â§Ú§Ö§ß§ä§Ú§â§à§Ó§Ñ§ß§ß§à§Û §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§í §Õ§Ý§ñ §ß§Ñ§á§Ú§ã§Ñ§ß§Ú§ñ Magento Extens...§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö §Ü§à§Þ§á§à§ß§Ö§ß§ä-§à§â§Ú§Ö§ß§ä§Ú§â§à§Ó§Ñ§ß§ß§à§Û §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§í §Õ§Ý§ñ §ß§Ñ§á§Ú§ã§Ñ§ß§Ú§ñ Magento Extens...
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö §Ü§à§Þ§á§à§ß§Ö§ß§ä-§à§â§Ú§Ö§ß§ä§Ú§â§à§Ó§Ñ§ß§ß§à§Û §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§í §Õ§Ý§ñ §ß§Ñ§á§Ú§ã§Ñ§ß§Ú§ñ Magento Extens...
Magecom Ukraine
?
§À§ß§Ú§ä §ä§Ö§ã§ä§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Zend Framework 2.0
§À§ß§Ú§ä §ä§Ö§ã§ä§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Zend Framework 2.0§À§ß§Ú§ä §ä§Ö§ã§ä§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Zend Framework 2.0
§À§ß§Ú§ä §ä§Ö§ã§ä§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Zend Framework 2.0
zfconfua
?
NoSQL §Ú Zend Framework (§¯§Ú§Ü§Ú§ä§Ñ §¤§â§à§ê§Ú§ß)
NoSQL §Ú Zend Framework (§¯§Ú§Ü§Ú§ä§Ñ §¤§â§à§ê§Ú§ß)NoSQL §Ú Zend Framework (§¯§Ú§Ü§Ú§ä§Ñ §¤§â§à§ê§Ú§ß)
NoSQL §Ú Zend Framework (§¯§Ú§Ü§Ú§ä§Ñ §¤§â§à§ê§Ú§ß)
zfconfua
?
§¬§Ý§ð§é §å§ã§á§Ö§ç§Ñ ¨C §á§â§à§è§Ö§ã§ã §Ú§Ý§Ú §á§â§à§Õ§å§Ü§ä?
§¬§Ý§ð§é §å§ã§á§Ö§ç§Ñ ¨C §á§â§à§è§Ö§ã§ã §Ú§Ý§Ú §á§â§à§Õ§å§Ü§ä?§¬§Ý§ð§é §å§ã§á§Ö§ç§Ñ ¨C §á§â§à§è§Ö§ã§ã §Ú§Ý§Ú §á§â§à§Õ§å§Ü§ä?
§¬§Ý§ð§é §å§ã§á§Ö§ç§Ñ ¨C §á§â§à§è§Ö§ã§ã §Ú§Ý§Ú §á§â§à§Õ§å§Ü§ä?
Magecom Ukraine
?
§µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §á§â§à§Õ§å§Ü§ä§à§Þ §Ó §ã§ä§Ú§Ý§Ö Magento Unified Process
§µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §á§â§à§Õ§å§Ü§ä§à§Þ §Ó §ã§ä§Ú§Ý§Ö Magento Unified Process§µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §á§â§à§Õ§å§Ü§ä§à§Þ §Ó §ã§ä§Ú§Ý§Ö Magento Unified Process
§µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §á§â§à§Õ§å§Ü§ä§à§Þ §Ó §ã§ä§Ú§Ý§Ö Magento Unified Process
Magecom Ukraine
?
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö TDD §á§â§Ú §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ö §Ó§Ö§Ò-§ã§Ö§â§Ó§Ú§ã§à§Ó
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö TDD §á§â§Ú §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ö §Ó§Ö§Ò-§ã§Ö§â§Ó§Ú§ã§à§Ó§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö TDD §á§â§Ú §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ö §Ó§Ö§Ò-§ã§Ö§â§Ó§Ú§ã§à§Ó
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö TDD §á§â§Ú §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ö §Ó§Ö§Ò-§ã§Ö§â§Ó§Ú§ã§à§Ó
Magecom Ukraine
?
§ª§ß§Õ§Ö§Ü§ã§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Magento
§ª§ß§Õ§Ö§Ü§ã§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Magento§ª§ß§Õ§Ö§Ü§ã§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Magento
§ª§ß§Õ§Ö§Ü§ã§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Magento
Magecom Ukraine
?
NoSQL §Ú Zend Framework (§²§à§ã§ä§Ú§ã§Ý§Ñ§Ó §®§Ú§ç§Ñ§Û§Ý§Ú§Ó)
NoSQL §Ú Zend Framework (§²§à§ã§ä§Ú§ã§Ý§Ñ§Ó §®§Ú§ç§Ñ§Û§Ý§Ú§Ó)NoSQL §Ú Zend Framework (§²§à§ã§ä§Ú§ã§Ý§Ñ§Ó §®§Ú§ç§Ñ§Û§Ý§Ú§Ó)
NoSQL §Ú Zend Framework (§²§à§ã§ä§Ú§ã§Ý§Ñ§Ó §®§Ú§ç§Ñ§Û§Ý§Ú§Ó)
zfconfua
?
§·§â§Ñ§ß§Ö§ß§Ú§Ö, §à§Ò§â§Ñ§Ò§à§ä§Ü§Ñ §Ú §à§ä§Õ§Ñ§é§Ñ §ã§ä§Ñ§ä§Ú§Ü§Ú §ã §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö§Þ \Zend\File. §°§á§í§ä §ã§à§è§Ú§Ñ§Ý...
§·§â§Ñ§ß§Ö§ß§Ú§Ö, §à§Ò§â§Ñ§Ò§à§ä§Ü§Ñ §Ú §à§ä§Õ§Ñ§é§Ñ §ã§ä§Ñ§ä§Ú§Ü§Ú §ã §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö§Þ \Zend\File. §°§á§í§ä §ã§à§è§Ú§Ñ§Ý...§·§â§Ñ§ß§Ö§ß§Ú§Ö, §à§Ò§â§Ñ§Ò§à§ä§Ü§Ñ §Ú §à§ä§Õ§Ñ§é§Ñ §ã§ä§Ñ§ä§Ú§Ü§Ú §ã §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö§Þ \Zend\File. §°§á§í§ä §ã§à§è§Ú§Ñ§Ý...
§·§â§Ñ§ß§Ö§ß§Ú§Ö, §à§Ò§â§Ñ§Ò§à§ä§Ü§Ñ §Ú §à§ä§Õ§Ñ§é§Ñ §ã§ä§Ñ§ä§Ú§Ü§Ú §ã §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö§Þ \Zend\File. §°§á§í§ä §ã§à§è§Ú§Ñ§Ý...
zfconfua
?
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö Scrum §Ú Kanban §Õ§Ý§ñ §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ú web-§á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö Scrum §Ú Kanban §Õ§Ý§ñ §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ú web-§á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö Scrum §Ú Kanban §Õ§Ý§ñ §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ú web-§á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö Scrum §Ú Kanban §Õ§Ý§ñ §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ú web-§á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û
Kirill Klimov
?
§±§â§Ö§Ú§Þ§å§ë§Ö§ã§ä§Ó§Ñ §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§ñ §á§à§Ý§ß§à§ä§Ö§Ü§ã§ä§à§Ó§à§Ô§à §á§à§Ú§ã§Ü§Ñ §Ó §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§Ñ§ç
§±§â§Ö§Ú§Þ§å§ë§Ö§ã§ä§Ó§Ñ §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§ñ §á§à§Ý§ß§à§ä§Ö§Ü§ã§ä§à§Ó§à§Ô§à §á§à§Ú§ã§Ü§Ñ §Ó §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§Ñ§ç§±§â§Ö§Ú§Þ§å§ë§Ö§ã§ä§Ó§Ñ §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§ñ §á§à§Ý§ß§à§ä§Ö§Ü§ã§ä§à§Ó§à§Ô§à §á§à§Ú§ã§Ü§Ñ §Ó §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§Ñ§ç
§±§â§Ö§Ú§Þ§å§ë§Ö§ã§ä§Ó§Ñ §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§ñ §á§à§Ý§ß§à§ä§Ö§Ü§ã§ä§à§Ó§à§Ô§à §á§à§Ú§ã§Ü§Ñ §Ó §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§Ñ§ç
Magecom Ukraine
?
§£§ã§Ö §Õ§à§â§à§Ô§Ú §Ó§Ö§Õ§å§ä §Ó Checkout
§£§ã§Ö §Õ§à§â§à§Ô§Ú §Ó§Ö§Õ§å§ä §Ó Checkout§£§ã§Ö §Õ§à§â§à§Ô§Ú §Ó§Ö§Õ§å§ä §Ó Checkout
§£§ã§Ö §Õ§à§â§à§Ô§Ú §Ó§Ö§Õ§å§ä §Ó Checkout
Magecom Ukraine
?
§¿§Ó§à§Ý§ð§è§Ú§ñ ZF: §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§Ñ, §ê§Ñ§Ò§Ý§à§ß§í, §â§Ö§æ§Ñ§Ü§ä§à§â§Ú§ß§Ô
§¿§Ó§à§Ý§ð§è§Ú§ñ ZF: §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§Ñ, §ê§Ñ§Ò§Ý§à§ß§í, §â§Ö§æ§Ñ§Ü§ä§à§â§Ú§ß§Ô§¿§Ó§à§Ý§ð§è§Ú§ñ ZF: §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§Ñ, §ê§Ñ§Ò§Ý§à§ß§í, §â§Ö§æ§Ñ§Ü§ä§à§â§Ú§ß§Ô
§¿§Ó§à§Ý§ð§è§Ú§ñ ZF: §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§Ñ, §ê§Ñ§Ò§Ý§à§ß§í, §â§Ö§æ§Ñ§Ü§ä§à§â§Ú§ß§Ô
zfconfua
?
§£§ã§ä§â§Ö§é§Ñ§Û§ä§Ö Zend Framework 2.0
§£§ã§ä§â§Ö§é§Ñ§Û§ä§Ö Zend Framework 2.0§£§ã§ä§â§Ö§é§Ñ§Û§ä§Ö Zend Framework 2.0
§£§ã§ä§â§Ö§é§Ñ§Û§ä§Ö Zend Framework 2.0
zfconfua
?
1000 §Þ§Ú§Ý§Ý§Ú§ã§Ö§Ü§å§ß§Õ §Ú§Ù §Ø§Ú§Ù§ß§Ú Magento
1000 §Þ§Ú§Ý§Ý§Ú§ã§Ö§Ü§å§ß§Õ §Ú§Ù §Ø§Ú§Ù§ß§Ú Magento1000 §Þ§Ú§Ý§Ý§Ú§ã§Ö§Ü§å§ß§Õ §Ú§Ù §Ø§Ú§Ù§ß§Ú Magento
1000 §Þ§Ú§Ý§Ý§Ú§ã§Ö§Ü§å§ß§Õ §Ú§Ù §Ø§Ú§Ù§ß§Ú Magento
Magecom Ukraine
?
§®§à§Ò§Ú§Ý§î§ß§í§Ö §Ü§Ý§Ú§Ö§ß§ä§í §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§à§Ó
§®§à§Ò§Ú§Ý§î§ß§í§Ö §Ü§Ý§Ú§Ö§ß§ä§í §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§à§Ó§®§à§Ò§Ú§Ý§î§ß§í§Ö §Ü§Ý§Ú§Ö§ß§ä§í §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§à§Ó
§®§à§Ò§Ú§Ý§î§ß§í§Ö §Ü§Ý§Ú§Ö§ß§ä§í §Ú§ß§ä§Ö§â§ß§Ö§ä-§Þ§Ñ§Ô§Ñ§Ù§Ú§ß§à§Ó
Magecom Ukraine
?
§²§Ö§Ñ§Ý§Ú§Ù§Ñ§è§Ú§ñ §ê§Ñ§Ò§Ý§à§ß§à§Ó §Ü§à§â§á§à§â§Ñ§ä§Ú§Ó§ß§í§ç §á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û §Ó Magento
§²§Ö§Ñ§Ý§Ú§Ù§Ñ§è§Ú§ñ §ê§Ñ§Ò§Ý§à§ß§à§Ó §Ü§à§â§á§à§â§Ñ§ä§Ú§Ó§ß§í§ç §á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û §Ó Magento§²§Ö§Ñ§Ý§Ú§Ù§Ñ§è§Ú§ñ §ê§Ñ§Ò§Ý§à§ß§à§Ó §Ü§à§â§á§à§â§Ñ§ä§Ú§Ó§ß§í§ç §á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û §Ó Magento
§²§Ö§Ñ§Ý§Ú§Ù§Ñ§è§Ú§ñ §ê§Ñ§Ò§Ý§à§ß§à§Ó §Ü§à§â§á§à§â§Ñ§ä§Ú§Ó§ß§í§ç §á§â§Ú§Ý§à§Ø§Ö§ß§Ú§Û §Ó Magento
Magecom Ukraine
?
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö §Ü§à§Þ§á§à§ß§Ö§ß§ä-§à§â§Ú§Ö§ß§ä§Ú§â§à§Ó§Ñ§ß§ß§à§Û §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§í §Õ§Ý§ñ §ß§Ñ§á§Ú§ã§Ñ§ß§Ú§ñ Magento Extens...
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö §Ü§à§Þ§á§à§ß§Ö§ß§ä-§à§â§Ú§Ö§ß§ä§Ú§â§à§Ó§Ñ§ß§ß§à§Û §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§í §Õ§Ý§ñ §ß§Ñ§á§Ú§ã§Ñ§ß§Ú§ñ Magento Extens...§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö §Ü§à§Þ§á§à§ß§Ö§ß§ä-§à§â§Ú§Ö§ß§ä§Ú§â§à§Ó§Ñ§ß§ß§à§Û §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§í §Õ§Ý§ñ §ß§Ñ§á§Ú§ã§Ñ§ß§Ú§ñ Magento Extens...
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö §Ü§à§Þ§á§à§ß§Ö§ß§ä-§à§â§Ú§Ö§ß§ä§Ú§â§à§Ó§Ñ§ß§ß§à§Û §Ñ§â§ç§Ú§ä§Ö§Ü§ä§å§â§í §Õ§Ý§ñ §ß§Ñ§á§Ú§ã§Ñ§ß§Ú§ñ Magento Extens...
Magecom Ukraine
?
§À§ß§Ú§ä §ä§Ö§ã§ä§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Zend Framework 2.0
§À§ß§Ú§ä §ä§Ö§ã§ä§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Zend Framework 2.0§À§ß§Ú§ä §ä§Ö§ã§ä§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Zend Framework 2.0
§À§ß§Ú§ä §ä§Ö§ã§ä§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Zend Framework 2.0
zfconfua
?
NoSQL §Ú Zend Framework (§¯§Ú§Ü§Ú§ä§Ñ §¤§â§à§ê§Ú§ß)
NoSQL §Ú Zend Framework (§¯§Ú§Ü§Ú§ä§Ñ §¤§â§à§ê§Ú§ß)NoSQL §Ú Zend Framework (§¯§Ú§Ü§Ú§ä§Ñ §¤§â§à§ê§Ú§ß)
NoSQL §Ú Zend Framework (§¯§Ú§Ü§Ú§ä§Ñ §¤§â§à§ê§Ú§ß)
zfconfua
?
§¬§Ý§ð§é §å§ã§á§Ö§ç§Ñ ¨C §á§â§à§è§Ö§ã§ã §Ú§Ý§Ú §á§â§à§Õ§å§Ü§ä?
§¬§Ý§ð§é §å§ã§á§Ö§ç§Ñ ¨C §á§â§à§è§Ö§ã§ã §Ú§Ý§Ú §á§â§à§Õ§å§Ü§ä?§¬§Ý§ð§é §å§ã§á§Ö§ç§Ñ ¨C §á§â§à§è§Ö§ã§ã §Ú§Ý§Ú §á§â§à§Õ§å§Ü§ä?
§¬§Ý§ð§é §å§ã§á§Ö§ç§Ñ ¨C §á§â§à§è§Ö§ã§ã §Ú§Ý§Ú §á§â§à§Õ§å§Ü§ä?
Magecom Ukraine
?
§µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §á§â§à§Õ§å§Ü§ä§à§Þ §Ó §ã§ä§Ú§Ý§Ö Magento Unified Process
§µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §á§â§à§Õ§å§Ü§ä§à§Þ §Ó §ã§ä§Ú§Ý§Ö Magento Unified Process§µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §á§â§à§Õ§å§Ü§ä§à§Þ §Ó §ã§ä§Ú§Ý§Ö Magento Unified Process
§µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §á§â§à§Õ§å§Ü§ä§à§Þ §Ó §ã§ä§Ú§Ý§Ö Magento Unified Process
Magecom Ukraine
?
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö TDD §á§â§Ú §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ö §Ó§Ö§Ò-§ã§Ö§â§Ó§Ú§ã§à§Ó
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö TDD §á§â§Ú §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ö §Ó§Ö§Ò-§ã§Ö§â§Ó§Ú§ã§à§Ó§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö TDD §á§â§Ú §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ö §Ó§Ö§Ò-§ã§Ö§â§Ó§Ú§ã§à§Ó
§±§â§Ú§Þ§Ö§ß§Ö§ß§Ú§Ö TDD §á§â§Ú §â§Ñ§Ù§â§Ñ§Ò§à§ä§Ü§Ö §Ó§Ö§Ò-§ã§Ö§â§Ó§Ú§ã§à§Ó
Magecom Ukraine
?
§ª§ß§Õ§Ö§Ü§ã§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Magento
§ª§ß§Õ§Ö§Ü§ã§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Magento§ª§ß§Õ§Ö§Ü§ã§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Magento
§ª§ß§Õ§Ö§Ü§ã§Ú§â§à§Ó§Ñ§ß§Ú§Ö §Ó Magento
Magecom Ukraine
?
NoSQL §Ú Zend Framework (§²§à§ã§ä§Ú§ã§Ý§Ñ§Ó §®§Ú§ç§Ñ§Û§Ý§Ú§Ó)
NoSQL §Ú Zend Framework (§²§à§ã§ä§Ú§ã§Ý§Ñ§Ó §®§Ú§ç§Ñ§Û§Ý§Ú§Ó)NoSQL §Ú Zend Framework (§²§à§ã§ä§Ú§ã§Ý§Ñ§Ó §®§Ú§ç§Ñ§Û§Ý§Ú§Ó)
NoSQL §Ú Zend Framework (§²§à§ã§ä§Ú§ã§Ý§Ñ§Ó §®§Ú§ç§Ñ§Û§Ý§Ú§Ó)
zfconfua
?

Similar to Doctrine 2 (20)

Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
Jonathan Wage
?
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
ddiers
?
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
?
15. CodeIgniter editarea inregistrarilor
15. CodeIgniter editarea inregistrarilor15. CodeIgniter editarea inregistrarilor
15. CodeIgniter editarea inregistrarilor
Razvan Raducanu, PhD
?
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
Alexandru Badiu
?
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
Benjamin Eberlei
?
Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09
Michelangelo van Dam
?
Doctrine for NoSQL
Doctrine for NoSQLDoctrine for NoSQL
Doctrine for NoSQL
Benjamin Eberlei
?
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
Leonardo Proietti
?
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
Jonathan Wage
?
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
?
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
chuvainc
?
Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!
Herman Peeren
?
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
Tricode (part of Dept)
?
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Rifat Nabi
?
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
Kris Wallsmith
?
From mysql to MongoDB£¨MongoDB2011±±¾©½»Á÷»á£©
From mysql to MongoDB£¨MongoDB2011±±¾©½»Á÷»á£©From mysql to MongoDB£¨MongoDB2011±±¾©½»Á÷»á£©
From mysql to MongoDB£¨MongoDB2011±±¾©½»Á÷»á£©
Night Sailer
?
Fatc
FatcFatc
Fatc
Wade Arnold
?
Laravel doctrine
Laravel doctrineLaravel doctrine
Laravel doctrine
Christian Nastasi
?
CodeIgniter Class Reference
CodeIgniter Class ReferenceCodeIgniter Class Reference
CodeIgniter Class Reference
Jamshid Hashimi
?
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
Jonathan Wage
?
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
ddiers
?
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
?
15. CodeIgniter editarea inregistrarilor
15. CodeIgniter editarea inregistrarilor15. CodeIgniter editarea inregistrarilor
15. CodeIgniter editarea inregistrarilor
Razvan Raducanu, PhD
?
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
Alexandru Badiu
?
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
Leonardo Proietti
?
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
Jonathan Wage
?
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
?
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
chuvainc
?
Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!
Herman Peeren
?
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
Tricode (part of Dept)
?
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Rifat Nabi
?
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
Kris Wallsmith
?
From mysql to MongoDB£¨MongoDB2011±±¾©½»Á÷»á£©
From mysql to MongoDB£¨MongoDB2011±±¾©½»Á÷»á£©From mysql to MongoDB£¨MongoDB2011±±¾©½»Á÷»á£©
From mysql to MongoDB£¨MongoDB2011±±¾©½»Á÷»á£©
Night Sailer
?
CodeIgniter Class Reference
CodeIgniter Class ReferenceCodeIgniter Class Reference
CodeIgniter Class Reference
Jamshid Hashimi
?

Doctrine 2

  • 2. Who am I? §£§Ñ§Ý§Ö§â§Ú§Û §²§Ñ§Ò§Ú§Ö§Ó§ã§Ü§Ú§Û Team lead §Ó§Ö§Ò-§ã§ä§å§Õ§Ú§Ú stfalcon.com §¡§Ü§ä§Ú§Ó§ß§í§Û §â§Ñ§Ù§â§Ñ§Ò§à§ä§é§Ú§Ü Open Source §Õ§Ó§Ú§Ø§Ü§Ñ ZFEngine (ZF + Doctrine) §¢§à§Ý§Ö§Ö 4 §Ý§Ö§ä §à§á§í§ä§Ñ §â§Ñ§Ò§à§ä§í §ã PHP
  • 4. §¢§Ú§Ò§Ý§Ú§à§ä§Ö§Ü§Ú ¡ª Common ¡ª DBAL (§Ó§Ü§Ý§ð§é§Ñ§Ö§ä Common) ¡ª ORM (§Ó§Ü§Ý§ð§é§Ñ§Ö§ä DBAL+Common) ¡ª Migrations (§é§Ñ§ã§ä§î DBAL) ¡ª Object Document Mapper: MongoDB CouchDB github.com/doctrine
  • 5. Entities ¡ª §­§Ö§Ô§Ü§Ñ§ñ §Þ§à§Õ§Ö§Ý§î (§ã§Ñ§Þ§í§Û §á§â§à§ã§ä§à§Û PHP §Ü§Ý§Ñ§ã§ã) ¡ª §¯§Ö §ß§å§Ø§ß§à §ß§Ñ§ã§Ý§Ö§Õ§à§Ó§Ñ§ß§Ú§Ö §à§ä §Ò§Ñ§Ù§à§Ó§à§Ô§à §Ü§Ý§Ñ§ã§ã§Ñ ¡ª §¦§ã§ä§î §Ó§à§Ù§Þ§à§Ø§ß§à§ã§ä§î §ß§Ñ§ã§Ý§Ö§Õ§à§Ó§Ñ§ä§î §Þ§à§Õ§Ö§Ý§î §à§ä §ã§Ó§à§Ú§ç §Ò§Ñ§Ù§à§Ó§í§ç §Ü§Ý§Ñ§ã§ã§à§Ó ¡ª §¬§à§ß§ã§ä§â§å§Ü§ä§à§â §Þ§à§Õ§Ö§Ý§Ú §Þ§à§Ø§ß§à §Ú§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ä§î §Õ§Ý§ñ §ã§Ó§à§Ú§ç §ß§å§Ø§Õ ¡ª §¥§Ñ§ß§ß§í§Ö §ç§â§Ñ§ß§ñ§ä§ã§ñ §ß§Ö§á§à§ã§â§Ö§Õ§ã§ä§Ó§Ö§ß§ß§à §Ó §ã§Ó§à§Û§ã§ä§Ó§Ñ§ç §à§Ò§ì§Ö§Ü§ä§Ñ
  • 6. §±§â§Ú§Þ§Ö§â §Þ§à§Õ§Ö§Ý§Ú namespace Entities; class User { private $id; private $name; public function getId() { return $this->id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } namespace Entities; class User { private $id; private $name; public function getId() { return $this->id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } }
  • 7. EntityManager EntityManager §ñ§Ó§Ý§ñ§Ö§ä§ã§ñ §è§Ö§ß§ä§â§Ñ§Ý§î§ß§à§Û §ä§à§é§Ü§à§Û §Õ§à§ã§ä§å§á§Ñ §Ü §æ§å§ß§Ü§è§Ú§ñ§Þ ORM ¡ª §µ§á§â§Ñ§Ó§Ý§Ö§ß§Ú§Ö §à§Ò§ß§à§Ó§Ý§Ö§ß§Ú§Ö§Þ §ã§å§ë§ß§à§ã§ä§Ö§Û ¡ª §¥§à§ã§ä§å§á §Ü §â§Ö§á§à§Ù§Ú§ä§à§â§Ú§ñ§Þ §ã§å§ë§ß§à§ã§ä§Ö§Û ¡ª §ª§ã§á§à§Ý§î§Ù§å§Ö§ä§ã§ñ §á§Ñ§ä§ä§Ö§â§ß UnitOfWork
  • 8. ZF2 + D2 protected function _initAutoload() { $loader = new ZendLoaderStandardAutoloader(); $loader->registerNamespace('Doctrine', '/path/to/Doctrine'); $loader->registerNamespace('Symfony', '/path/to/Symfony'); $loader->register(); } protected function _initAutoload() { $loader = new ZendLoaderStandardAutoloader(); $loader->registerNamespace('Doctrine', '/path/to/Doctrine'); $loader->registerNamespace('Symfony', '/path/to/Symfony'); $loader->register(); } §¥§à§Ò§Ñ§Ó§Ý§ñ§Ö§Þ §Ñ§Ó§ä§à§Ù§Ñ§Ô§â§å§Ù§Ü§å §Ó Bootstrap
  • 9. §¯§Ñ§ã§ä§â§à§Û§Ü§Ñ Doctrine 2 ./application/configs/application.xml <!-- production --> <doctrine> <connection><!-- user, password, database, etc --></connection> <paths> <entities>path/to/entities</entities> <proxies>path/to/proxies</proxies> </paths> <proxiesNamespace value="ApplicationModelProxies" /> <autogenerateProxyClasses value="0" /> <cacheAdapter value="DoctrineCommonCacheApcCache" /> </doctrine> <!-- development --> ... <autogenerateProxyClasses value="1" /> <cacheAdapter value="DoctrineCommonCacheArrayCache" /> ¡­ <!-- production --> <doctrine> <connection><!-- user, password, database, etc --></connection> <paths> <entities>path/to/entities</entities> <proxies>path/to/proxies</proxies> </paths> <proxiesNamespace value="ApplicationModelProxies" /> <autogenerateProxyClasses value="0" /> <cacheAdapter value="DoctrineCommonCacheApcCache" /> </doctrine> <!-- development --> ... <autogenerateProxyClasses value="1" /> <cacheAdapter value="DoctrineCommonCacheArrayCache" /> ¡­
  • 10. §±§à§Õ§Ü§Ý§ð§é§Ö§ß§Ú§Ö EntityManager protected function _initEntityManager() { if (is_null($this->_em)) { $options = $this->getOption('doctrine'); $cache = new $options['cacheAdapter']; $config = new Configuration(); $driverImpl = $config ->newDefaultAnnotationDriver($options['paths']['entities']); $config->setMetadataCacheImpl($cache); $config->setMetadataDriverImpl($driverImpl); $config->setQueryCacheImpl($cache); $config->setProxyNamespace($options['proxiesNamespace']); $config->setProxyDir($options['paths']['proxies']); $config->setAutoGenerateProxyClasses( $options['autogenerateProxyClasses'] ); $this->_em = EntityManager::create($options['connection'], $config); } return $this->_em; } protected function _initEntityManager() { if (is_null($this->_em)) { $options = $this->getOption('doctrine'); $cache = new $options['cacheAdapter']; $config = new Configuration(); $driverImpl = $config ->newDefaultAnnotationDriver($options['paths']['entities']); $config->setMetadataCacheImpl($cache); $config->setMetadataDriverImpl($driverImpl); $config->setQueryCacheImpl($cache); $config->setProxyNamespace($options['proxiesNamespace']); $config->setProxyDir($options['paths']['proxies']); $config->setAutoGenerateProxyClasses( $options['autogenerateProxyClasses'] ); $this->_em = EntityManager::create($options['connection'], $config); } return $this->_em; }
  • 12. Basic Mapping ¡ª Docblock Annotations ¡ª XML ¡ª YAML ¡ª PHP
  • 13. Association Mapping ¡ª One-To-One & Many-To-Many: ¡ª Unidirectional ¡ª Bidirectional ¡ª Self-referencing ¡ª Many-To-One, Unidirectional ¡ª One-To-Many: ¡ª Unidirectional with Join Table ¡ª Bidirectional ¡ª Self-referencing
  • 14. Inheritance Mapping ¡ª Mapped Superclasses ¡ª Single Table Inheritance ¡ª Class Table Inheritance
  • 15. Mapping ... /** * @ManyToOne(targetEntity="Address", inversedBy="users") * @JoinColumn(name="address_id", referencedColumnName="id") */ private $address; ... ... /** * @ManyToOne(targetEntity="Address", inversedBy="users") * @JoinColumn(name="address_id", referencedColumnName="id") */ private $address; ... ... /** @OneToMany(targetEntity="User", mappedBy="address") */ private $user; ... ... /** @OneToMany(targetEntity="User", mappedBy="address") */ private $user; ... Entities/User Entitites/Address
  • 17. Console ... $em = $application->getBootstrap()->getResource('EntityManager'); ... $helpers = array( 'db' => new DBALHelperConnectionHelper($em->getConnection()), 'em' => new ORMHelperEntityManagerHelper($em), 'dialog' => new SymfonyComponentConsoleHelperDialogHelper(), ); ... $cli = new SymfonyComponentConsoleApplication( 'Doctrine Command Line Interface', DoctrineCommonVersion::VERSION); $cli->setCatchExceptions(true); ... $cli->addCommands(array( new DBALCommandRunSqlCommand(), new ORMCommandValidateSchemaCommand(), new MigrationsCommandVersionCommand() )); $cli->run(); ... $em = $application->getBootstrap()->getResource('EntityManager'); ... $helpers = array( 'db' => new DBALHelperConnectionHelper($em->getConnection()), 'em' => new ORMHelperEntityManagerHelper($em), 'dialog' => new SymfonyComponentConsoleHelperDialogHelper(), ); ... $cli = new SymfonyComponentConsoleApplication( 'Doctrine Command Line Interface', DoctrineCommonVersion::VERSION); $cli->setCatchExceptions(true); ... $cli->addCommands(array( new DBALCommandRunSqlCommand(), new ORMCommandValidateSchemaCommand(), new MigrationsCommandVersionCommand() )); $cli->run();
  • 18. Console $ ./doctrine Doctrine Command Line Interface version 2.0.0RC3-DEV Usage: [options] command [arguments] dbal :import :run-sql orm :convert-d1-schema :convert-mapping :generate-proxies :generate-repositories :run-dql :validate-schema orm:clear-cache :metadata :query :result $ ./doctrine Doctrine Command Line Interface version 2.0.0RC3-DEV Usage: [options] command [arguments] dbal :import :run-sql orm :convert-d1-schema :convert-mapping :generate-proxies :generate-repositories :run-dql :validate-schema orm:clear-cache :metadata :query :result
  • 19. Console: ORM $ ./doctrine orm:ensure-production-settings Proxy Classes are always regenerating. $ ./doctrine orm:ensure-production-settings SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' $ ./doctrine orm:ensure-production-settings Environment is correctly configured for production. $ ./doctrine orm:ensure-production-settings Proxy Classes are always regenerating. $ ./doctrine orm:ensure-production-settings SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' $ ./doctrine orm:ensure-production-settings Environment is correctly configured for production. §±§â§à§Ó§Ö§â§Ü§Ñ §Ü§à§â§â§Ö§Ü§ä§ß§à§ã§ä§Ú §ß§Ñ§ã§ä§â§à§Ö§Ü §Õ§Ý§ñ production
  • 20. Console: ORM §£§Ñ§Ý§Ú§Õ§Ñ§è§Ú§ñ §Þ§à§Õ§Ö§Ý§Ú $ ./doctrine orm:validate-schema [Mapping] FAIL - The entity-class 'EntitiesAddress' mapping is invalid: * The field EntitiesAddress#user is on the inverse side of a bi-directional Relationship, but the specified mappedBy association on the target-entity EntitiesUser#address does not contain the required 'inversedBy' attribute. [Database] FAIL - The database schema is not in sync with the current mapping file. $ ./doctrine orm:validate-schema [Mapping] FAIL - The entity-class 'EntitiesAddress' mapping is invalid: * The field EntitiesAddress#user is on the inverse side of a bi-directional Relationship, but the specified mappedBy association on the target-entity EntitiesUser#address does not contain the required 'inversedBy' attribute. [Database] FAIL - The database schema is not in sync with the current mapping file.
  • 22. Migrations §¹§ä§à §ß§å§Ø§ß§à: ¡ª §ã§ä§Ñ§ß§Õ§Ñ§â§ä§ß§í§Û §ã§Ü§â§Ú§á§ä §Õ§Ý§ñ §á§à§Õ§Ü§Ý§ð§é§Ö§ß§Ú§ñ §Ü§à§ß§ã§à§Ý§Ú ¡ª §Ó §á§Ñ§á§Ü§å §ã §ã§Ü§â§Ú§á§ä§à§Þ §Õ§à§Ò§Ñ§Ó§Ú§ä§î migrations.xml (§Ú§Ý§Ú yaml) <doctrine-migrations> <name>Doctrine Migrations</name> <migrations-namespace> DoctrineMigrations </migrations-namespace> <table name="migration_versions" /> <migrations-directory>/path/to/migrations/</migrations-directory> </doctrine-migrations> <doctrine-migrations> <name>Doctrine Migrations</name> <migrations-namespace> DoctrineMigrations </migrations-namespace> <table name="migration_versions" /> <migrations-directory>/path/to/migrations/</migrations-directory> </doctrine-migrations>
  • 23. Migrations §¥§à§ã§ä§å§á§ß§í§Ö §Ü§à§Þ§Ñ§ß§Õ§í $ ./doctrine ... migrations :diff :generate :status :execute :migrate :version ... $ ./doctrine ... migrations :diff :generate :status :execute :migrate :version ...
  • 24. Migrations §¶§Ú§Ü§ã§Ú§â§å§Ö§Þ §Ú§Ù§Þ§Ö§ß§Ö§ß§Ú§ñ §Ó §Þ§Ú§Ô§â§Ñ§è§Ú§Ú $ ./doctrine migrations:diff Generated new migration class to "path/to/migrations/Version20101124201328.php" from schema differences. $ ./doctrine migrations:diff Generated new migration class to "path/to/migrations/Version20101124201328.php" from schema differences. namespace DoctrineMigrations; class Version20101124201328 extends AbstractMigration { public function up(Schema $schema) { $this->_addSql('CREATE TABLE users (...) ENGINE = InnoDB'); } public function down(Schema $schema) { $this->_addSql('DROP TABLE users'); } } namespace DoctrineMigrations; class Version20101124201328 extends AbstractMigration { public function up(Schema $schema) { $this->_addSql('CREATE TABLE users (...) ENGINE = InnoDB'); } public function down(Schema $schema) { $this->_addSql('DROP TABLE users'); } }
  • 25. Migrations §¯§Ñ§Ü§Ñ§ä§í§Ó§Ñ§ß§Ú§Ö §Þ§Ú§Ô§â§Ñ§è§Ú§Ú $ ./doctrine migrations:migrate --dry-run Executing dry run of migration up to 20101124201328 from 0 ++ migrating 20101124201328 -> CREATE TABLE users ( ... ) ENGINE = InnoDB ++ migrated (0.01s) ------------------------ ++ finished in 0.01 ++ 1 migrations executed ++ 1 sql queries $ ./doctrine migrations:migrate --dry-run Executing dry run of migration up to 20101124201328 from 0 ++ migrating 20101124201328 -> CREATE TABLE users ( ... ) ENGINE = InnoDB ++ migrated (0.01s) ------------------------ ++ finished in 0.01 ++ 1 migrations executed ++ 1 sql queries
  • 26. Migrations §¤§Ö§ß§Ö§â§Ú§â§å§Ö§Þ §Ù§Ñ§Ô§à§ä§à§Ó§Ü§å §Þ§Ú§Ô§â§Ñ§è§Ú§Ú $ ./doctrine migrations:generate --editor-cmd=netbeans Generated new migration class to "path/to/migrations/Version20101124201328.php" $ ./doctrine migrations:generate --editor-cmd=netbeans Generated new migration class to "path/to/migrations/Version20101124201328.php" namespace DoctrineMigrations; class Version20101124201328 extends AbstractMigration { public function up(Schema $schema) { // $this->_addSql('CREATE TABLE users (...) ENGINE = InnoDB'); $table = $schema->createTable('users'); $table->addColumn('username', 'string'); } public function down(Schema $schema) { $schema->dropTable('users'); } } namespace DoctrineMigrations; class Version20101124201328 extends AbstractMigration { public function up(Schema $schema) { // $this->_addSql('CREATE TABLE users (...) ENGINE = InnoDB'); $table = $schema->createTable('users'); $table->addColumn('username', 'string'); } public function down(Schema $schema) { $schema->dropTable('users'); } }
  • 27. §ª§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö §±§â§Ú§Þ§Ö§â §â§Ñ§Ò§à§ä§í §ã §Þ§à§Õ§Ö§Ý§ñ§Þ§Ú $em = $this->getInvokeArg('bootstrap') ->getResource('EntityManager'); $address = new EntitiesAddress(); $address->setStreet('§¬§Ú§Ö§Ó§ã§Ü§Ñ§ñ, 1'); $user = new EntitiesUser(); $user->setName('§£§Ñ§ß§ñ'); $user->setAddress($address); $em->persist($address); $em->persist($user); $em->flush(); $em = $this->getInvokeArg('bootstrap') ->getResource('EntityManager'); $address = new EntitiesAddress(); $address->setStreet('§¬§Ú§Ö§Ó§ã§Ü§Ñ§ñ, 1'); $user = new EntitiesUser(); $user->setName('§£§Ñ§ß§ñ'); $user->setAddress($address); $em->persist($address); $em->persist($user); $em->flush();
  • 28. §ª§ã§á§à§Ý§î§Ù§à§Ó§Ñ§ß§Ú§Ö §±§â§Ú§Þ§Ö§â §â§Ñ§Ò§à§ä§í §ã §Þ§à§Õ§Ö§Ý§ñ§Þ§Ú $user = $em->find('EntitiesUser', 1); $user->getAddress(); // ¡ú object ProxiesEntitiesAddressProxy $user->getName(); // §£§Ñ§ß§ñ $user->setName('§±§Ö§ä§ñ'); $em->flush(); ... $user = $em->find('EntitiesUser', 1); $user->getName(); // §±§Ö§ä§ñ $user = $em->find('EntitiesUser', 1); $user->getAddress(); // ¡ú object ProxiesEntitiesAddressProxy $user->getName(); // §£§Ñ§ß§ñ $user->setName('§±§Ö§ä§ñ'); $em->flush(); ... $user = $em->find('EntitiesUser', 1); $user->getName(); // §±§Ö§ä§ñ
  • 29. Doctrine Query Language Doctrine 1 ¡ª §¯§Ö §Ò§í§Ý§à §â§Ö§Ñ§Ý§î§ß§à§Ô§à §á§Ñ§â§ã§Ö§â§Ñ DQL Doctrine 2 ¡ª Abstract Syntax Tree
  • 31. Behaviors §¯§Ö§ä §Ú §ß§Ö §Ò§å§Õ§Ö§ä §â§Ñ§ã§ê§Ú§â§Ö§ß§Ú§Û ?§Ú§Ù §Ü§à§â§à§Ò§Ü§Ú? Events & Subscribers+ ?
  • 32. Events namespace Entities; /** * @HasLifecycleCallbacks */ class User { ¡­ /** @PrePersist */ public function updateCreatedAt() { $this->createdAt = date('Y-m-d H:m:s'); } } namespace Entities; /** * @HasLifecycleCallbacks */ class User { ¡­ /** @PrePersist */ public function updateCreatedAt() { $this->createdAt = date('Y-m-d H:m:s'); } }
  • 33. Lifecycle Events ¡ª pre/postRemove ¡ª pre/postPersist ¡ª pre/postUpdate ¡ª postLoad ¡ª loadClassMetadata ¡ª onFlush
  • 34. Event Listeners §±§â§à§ã§ä§Ö§Û§ê§Ú§Û §á§à§Õ§á§Ú§ã§é§Ú§Ü §ß§Ñ §ã§à§Ò§í§ä§Ú§ñ class MyEventSubscriber implements EventSubscriber { public function getSubscribedEvents() { return array( Events::preUpdate ); } public function preUpdate(PreUpdateEventArgs $eventArgs) { if ($eventArgs->getEntity() instanceof User) { if ($eventArgs->hasChangedField('name')) { /*§ß§Ñ§ê §Ü§à§Õ*/ } } } } $entityManager->getEventManager() ->addEventSubscriber(new MyEventSubscriber()); class MyEventSubscriber implements EventSubscriber { public function getSubscribedEvents() { return array( Events::preUpdate ); } public function preUpdate(PreUpdateEventArgs $eventArgs) { if ($eventArgs->getEntity() instanceof User) { if ($eventArgs->hasChangedField('name')) { /*§ß§Ñ§ê §Ü§à§Õ*/ } } } } $entityManager->getEventManager() ->addEventSubscriber(new MyEventSubscriber());
  • 35. Behavioral Extensions goo.gl/Mgnwg (www.doctrine-project.org/blog/doctrine2-behavioral-extensions) ... /** * @gedmo:Timestampable(on="create") * @Column(type="date") */ private $created; /** * @gedmo:Timestampable(on="update") * @Column(type="datetime") */ private $updated; ... ... /** * @gedmo:Timestampable(on="create") * @Column(type="date") */ private $created; /** * @gedmo:Timestampable(on="update") * @Column(type="datetime") */ private $updated; ...
  • 36. §²§Ö§á§Ý§Ú§Ü§Ñ§è§Ú§ñ Doctrine 1 $connections = array( 'master' => 'mysql://root:@master/dbname', 'slave_1' => 'mysql://root:@slave1/dbname', 'slave_2' => 'mysql://root:@slave2/dbname', ); foreach ($connections as $name => $dsn) { Doctrine_Manager::connection($dsn, $name); } $connections = array( 'master' => 'mysql://root:@master/dbname', 'slave_1' => 'mysql://root:@slave1/dbname', 'slave_2' => 'mysql://root:@slave2/dbname', ); foreach ($connections as $name => $dsn) { Doctrine_Manager::connection($dsn, $name); }
  • 37. §²§Ö§á§Ý§Ú§Ü§Ñ§è§Ú§ñ Doctrine 1 Doctrine 2 :( $connections = array( 'master' => 'mysql://root:@master/dbname', 'slave_1' => 'mysql://root:@slave1/dbname', 'slave_2' => 'mysql://root:@slave2/dbname', ); foreach ($connections as $name => $dsn) { Doctrine_Manager::connection($dsn, $name); } $connections = array( 'master' => 'mysql://root:@master/dbname', 'slave_1' => 'mysql://root:@slave1/dbname', 'slave_2' => 'mysql://root:@slave2/dbname', ); foreach ($connections as $name => $dsn) { Doctrine_Manager::connection($dsn, $name); }
  • 38. §²§Ö§á§Ý§Ú§Ü§Ñ§è§Ú§ñ §£ Doctrine 2 §Ó§ã§Ö §Õ§Ö§Û§ã§ä§Ó§Ú§ñ §ã §Þ§à§Õ§Ö§Ý§î§ð §á§â§à§Ú§ã§ç§à§Õ§ñ§ä §é§Ö§â§Ö§Ù EntityManager §©§ß§Ñ§é§Ú§ä §Þ§à§Ø§ß§à: ¡ª §ã§à§Ù§Õ§Ñ§ä§î §ß§Ö§ã§Ü§à§Ý§î§Ü§à EM §ß§Ñ §Ü§Ñ§Ø§Õ§à§Ö §á§à§Õ§Ü§Ý§ð§é§Ö§ß§Ú§Ö; ¡ª §â§Ñ§ã§ê§Ú§â§Ú§ä§î §ã§ä§Ñ§ß§Õ§Ñ§â§ä§ß§í§Û EM §á§à§Õ§Õ§Ö§â§Ø§Ü§à§Û §â§Ö§á§Ý§Ú§Ü§Ñ§è§Ú§Û;
  • 39. §±§â§Ö§Õ§á§à§ã§Ý§Ö§Õ§ß§ñ§ñ §ª§ã§ç§à§Õ§ß§í§Û §Ü§à§Õ §Þ§à§Ú§ç §ï§Ü§ã§á§Ö§â§Ú§Þ§Ö§ß§ä§à§Ó §ã ZF2 §Ú Doctrine 2 §ã§Ü§à§â§à §á§à§ñ§Ó§Ú§ä§ã§ñ §ß§Ñ GitHub'e: github.com/ftrrtf
  • 40. §³§á§Ñ§ã§Ú§Ò§à §Ù§Ñ §Ó§ß§Ú§Þ§Ñ§ß§Ú§Ö! §¦§ã§ä§î §Ó§à§á§â§à§ã§í? §£§Ñ§Ý§Ö§â§Ú§Û §²§Ñ§Ò§Ú§Ö§Ó§ã§Ü§Ú§Û mail@ftrrtf.com twitter.com/ftrrtf facebook.com/ftrrtf