26. Tools¶
26.1. Doctrine Console¶
The Doctrine Console is a Command Line Interface tool for simplifying common administration tasks during the development of a project that uses ORM.
For the following examples, we will set up the CLI as bin/doctrine
.
26.1.1. Setting Up the Console¶
Whenever the doctrine
command line tool is invoked, it can
access all Commands that were registered by a developer. There is no
auto-detection mechanism at work. The Doctrine binary
already registers all the commands that currently ship with
Doctrine DBAL and ORM. If you want to use additional commands you
have to register them yourself.
All the commands of the Doctrine Console require access to the
EntityManager
. You have to inject it into the console application.
Here is an example of a the project-specific bin/doctrine
binary.
#!/usr/bin/env php
<?php
use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
// replace with path to your own project bootstrap file
require_once 'bootstrap.php';
// replace with mechanism to retrieve EntityManager in your app
$entityManager = GetEntityManager();
$commands = [
// If you want to add your own custom console commands,
// you can do so here.
];
ConsoleRunner::run(
new SingleManagerProvider($entityManager),
$commands
);
Note
You have to adjust this snippet for your specific application or framework and use their facilities to access the Doctrine EntityManager and Connection Resources.
26.1.2. Display Help Information¶
Type php bin/doctrine
on the command line and you should see an
overview of the available commands or use the --help
flag to get
information on the available commands. If you want to know more
about the use of generate entities for example, you can call:
$> php bin/doctrine orm:generate-entities --help
26.1.3. Command Overview¶
The following Commands are currently available:
help
Displays help for a command (?)help コマンドのヘルプを表示します (?)list
Lists commandslist コマンドを一覧表示しますdbal:import
Import SQL file(s) directly to Database.dbal:import SQL ファイルをデータベースに直接インポートします。dbal:run-sql
Executes arbitrary SQL directly from the command line.dbal:run-sql コマンドラインから任意の SQL を直接実行します。orm:clear-cache:metadata
Clear all metadata cache of the various cache drivers.orm:clear-cache:metadata さまざまなキャッシュ ドライバのすべてのメタデータ キャッシュをクリアします。orm:clear-cache:query
Clear all query cache of the various cache drivers.orm:clear-cache:query さまざまなキャッシュ ドライバのすべてのクエリ キャッシュをクリアします。orm:clear-cache:result
Clear result cache of the various cache drivers.orm:clear-cache:result さまざまなキャッシュ ドライバの結果キャッシュをクリアします。orm:convert-d1-schema
Converts Doctrine 1.X schema into a Doctrine 2.X schema.orm:convert-d1-schema Doctrine 1.X スキーマを Doctrine 2.X スキーマに変換します。orm:convert-mapping
Convert mapping information between supported formats.orm:convert-mapping サポートされているフォーマット間でマッピング情報を変換します。orm:ensure-production-settings
Verify that Doctrine is properly configured for a production environment.orm:ensure-production-settings Doctrine が本番環境用に適切に設定されていることを確認します。orm:generate-entities
Generate entity classes and method stubs from your mapping information.orm:generate-entities マッピング情報からエンティティ クラスとメソッドタブを生成します。orm:generate-proxies
Generates proxy classes for entity classes.orm:generate-proxies エンティティ クラスのプロキシ クラスを生成します。orm:generate-repositories
Generate repository classes from your mapping information.orm:generate-repositories マッピング情報からリポジトリ クラスを生成します。orm:run-dql
Executes arbitrary DQL directly from the command line.orm:run-dql コマンドラインから任意の DQL を直接実行します。orm:schema-tool:create
Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.orm:schema-tool:create スキーマを処理し、EntityManager ストレージ接続で直接作成するか、SQL 出力を生成します。orm:schema-tool:drop
Processes the schema and either drop the database schema of EntityManager Storage Connection or generate the SQL output.orm:schema-tool:drop スキーマを処理し、EntityManager Storage Connection のデータベース スキーマを削除するか、SQL 出力を生成します。orm:schema-tool:update
Processes the schema and either update the database schema of EntityManager Storage Connection or generate the SQL output.orm:schema-tool:update スキーマを処理し、EntityManager Storage Connection のデータベース スキーマを更新するか、SQL 出力を生成します。
For these commands are also available aliases:
orm:convert:d1-schema
is alias fororm:convert-d1-schema
.orm:convert:d1-schema は orm:convert-d1-schema のエイリアスです。orm:convert:mapping
is alias fororm:convert-mapping
.orm:convert:mapping は orm:convert-mapping のエイリアスです。orm:generate:entities
is alias fororm:generate-entities
.orm:generate:entities は orm:generate-entities のエイリアスです。orm:generate:proxies
is alias fororm:generate-proxies
.orm:generate:proxies は、orm:generate-proxies のエイリアスです。orm:generate:repositories
is alias fororm:generate-repositories
.orm:generate:repositories は orm:generate-repositories のエイリアスです。
Note
Console also supports auto completion, for example, instead of
orm:clear-cache:query
you can use just o:c:q
.
26.2. Database Schema Generation¶
Note
SchemaTool can do harm to your database. It will drop or alter tables, indexes, sequences and such. Please use this tool with caution in development and not on a production server. It is meant for helping you develop your Database Schema, but NOT with migrating schema from A to B in production. A safe approach would be generating the SQL on development server and saving it into SQL Migration files that are executed manually on the production server.
SchemaTool assumes your Doctrine Project uses the given database on its own. Update and Drop commands will mess with other tables if they are not related to the current project that is using Doctrine. Please be careful!
To generate your database schema from your Doctrine mapping files
you can use the SchemaTool
class or the schema-tool
Console
Command.
When using the SchemaTool class directly, create your schema using
the createSchema()
method. First create an instance of the
SchemaTool
and pass it an instance of the EntityManager
that you want to use to create the schema. This method receives an
array of ClassMetadata
instances.
<?php
$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
$classes = array(
$em->getClassMetadata('Entities\User'),
$em->getClassMetadata('Entities\Profile')
);
$tool->createSchema($classes);
To drop the schema you can use the dropSchema()
method.
<?php
$tool->dropSchema($classes);
This drops all the tables that are currently used by your metadata model. When you are changing your metadata a lot during development you might want to drop the complete database instead of only the tables of the current model to clean up with orphaned tables.
<?php
$tool->dropSchema($classes, \Doctrine\ORM\Tools\SchemaTool::DROP_DATABASE);
You can also use database introspection to update your schema
easily with the updateSchema()
method. It will compare your
existing database schema to the passed array of ClassMetadata
instances.
<?php
$tool->updateSchema($classes);
If you want to use this functionality from the command line you can
use the schema-tool
command.
To create the schema use the create
command:
$ php bin/doctrine orm:schema-tool:create
To drop the schema use the drop
command:
$ php bin/doctrine orm:schema-tool:drop
If you want to drop and then recreate the schema then use both options:
$ php bin/doctrine orm:schema-tool:drop
$ php bin/doctrine orm:schema-tool:create
As you would think, if you want to update your schema use the
update
command:
$ php bin/doctrine orm:schema-tool:update
All of the above commands also accept a --dump-sql
option that
will output the SQL for the ran operation.
$ php bin/doctrine orm:schema-tool:create --dump-sql
26.3. Entity Generation¶
Generate entity classes and method stubs from your mapping information.
$ php bin/doctrine orm:generate-entities
$ php bin/doctrine orm:generate-entities --update-entities
$ php bin/doctrine orm:generate-entities --regenerate-entities
This command is not suited for constant usage. It is a little helper and does not support all the mapping edge cases very well. You still have to put work in your entities after using this command.
It is possible to use the EntityGenerator on code that you have already written. It will not be lost. The EntityGenerator will only append new code to your file and will not delete the old code. However this approach may still be prone to error and we suggest you use code repositories such as GIT or SVN to make backups of your code.
It makes sense to generate the entity code if you are using entities as Data Access Objects only and don’t put much additional logic on them. If you are however putting much more logic on the entities you should refrain from using the entity-generator and code your entities manually.
Note
Even if you specified Inheritance options in your XML or YAML Mapping files the generator cannot generate the base and child classes for you correctly, because it doesn’t know which class is supposed to extend which. You have to adjust the entity code manually for inheritance to work!
26.4. Convert Mapping Information¶
Convert mapping information between supported formats.
This is an execute one-time command. It should not be necessary for
you to call this method multiple times, especially when using the --from-database
flag.
Converting an existing database schema into mapping files only solves about 70-80% of the necessary mapping information. Additionally the detection from an existing database cannot detect inverse associations, inheritance types, entities with foreign keys as primary keys and many of the semantical operations on associations such as cascade.
Note
There is no need to convert YAML or XML mapping files to annotations every time you make changes. All mapping drivers are first class citizens in Doctrine 2 and can be used as runtime mapping for the ORM. See the docs on XML and YAML Mapping for an example how to register this metadata drivers as primary mapping source.
To convert some mapping information between the various supported
formats you can use the ClassMetadataExporter
to get exporter
instances for the different formats:
<?php
$cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter();
Once you have a instance you can use it to get an exporter. For example, the yml exporter:
<?php
$exporter = $cme->getExporter('yml', '/path/to/export/yml');
Now you can export some ClassMetadata
instances:
<?php
$classes = array(
$em->getClassMetadata('Entities\User'),
$em->getClassMetadata('Entities\Profile')
);
$exporter->setMetadata($classes);
$exporter->export();
This functionality is also available from the command line to
convert your loaded mapping information to another format. The
orm:convert-mapping
command accepts two arguments, the type to
convert to and the path to generate it:
$ php bin/doctrine orm:convert-mapping xml /path/to/mapping-path-converted-to-xml
26.5. Reverse Engineering¶
You can use the DatabaseDriver
to reverse engineer a database to an
array of ClassMetadata
instances and generate YAML, XML, etc. from
them.
Note
Reverse Engineering is a one-time process that can get you started with a project. Converting an existing database schema into mapping files only detects about 70-80% of the necessary mapping information. Additionally the detection from an existing database cannot detect inverse associations, inheritance types, entities with foreign keys as primary keys and many of the semantical operations on associations such as cascade.
First you need to retrieve the metadata instances with the
DatabaseDriver
:
<?php
$em->getConfiguration()->setMetadataDriverImpl(
new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$em->getConnection()->getSchemaManager()
)
);
$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
$metadata = $cmf->getAllMetadata();
Now you can get an exporter instance and export the loaded metadata to yml:
<?php
$cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter();
$exporter = $cme->getExporter('yml', '/path/to/export/yml');
$exporter->setMetadata($metadata);
$exporter->export();
You can also reverse engineer a database using the
orm:convert-mapping
command:
$ php bin/doctrine orm:convert-mapping --from-database yml /path/to/mapping-path-converted-to-yml
Note
Reverse Engineering is not always working perfectly depending on special cases. It will only detect Many-To-One relations (even if they are One-To-One) and will try to create entities from Many-To-Many tables. It also has problems with naming of foreign keys that have multiple column names. Any Reverse Engineered Database-Schema needs considerable manual work to become a useful domain model.
26.6. Runtime vs Development Mapping Validation¶
For performance reasons Doctrine ORM has to skip some of the necessary validation of metadata mappings. You have to execute this validation in your development workflow to verify the associations are correctly defined.
You can either use the Doctrine Command Line Tool:
doctrine orm:validate-schema
If the validation fails, you can change the verbosity level to check the detected errors:
doctrine orm:validate-schema -v
doctrine orm:validate-schema -v
Or you can trigger the validation manually:
<?php
use Doctrine\ORM\Tools\SchemaValidator;
$validator = new SchemaValidator($entityManager);
$errors = $validator->validateMapping();
if (count($errors) > 0) {
// Lots of errors!
echo implode("\n\n", $errors);
}
If the mapping is invalid the errors array contains a positive number of elements with error messages.
Warning
One mapping option that is not validated is the use of the referenced column name. It has to point to the equivalent primary key otherwise Doctrine will not work.
Note
One common error is to use a backlash in front of the
fully-qualified class-name. Whenever a FQCN is represented inside a
string (such as in your mapping definitions) you have to drop the
prefix backslash. PHP does this with get_class()
or Reflection
methods for backwards compatibility reasons.
26.7. Adding own commands¶
You can also add your own commands on-top of the Doctrine supported tools if you are using a manually built console script.
To include a new command on Doctrine Console, you need to do modify the
doctrine.php
file a little:
<?php
// doctrine.php
use Symfony\Component\Console\Application;
// as before ...
// replace the ConsoleRunner::run() statement with:
$cli = new Application('Doctrine Command Line Interface', \Doctrine\ORM\Version::VERSION);
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);
// Register All Doctrine Commands
ConsoleRunner::addCommands($cli);
// Register your own command
$cli->addCommand(new \MyProject\Tools\Console\Commands\MyCustomCommand);
// Runs console application
$cli->run();
Additionally, include multiple commands (and overriding previously defined ones) is possible through the command:
<?php
$cli->addCommands(array(
new \MyProject\Tools\Console\Commands\MyCustomCommand(),
new \MyProject\Tools\Console\Commands\SomethingCommand(),
new \MyProject\Tools\Console\Commands\AnotherCommand(),
new \MyProject\Tools\Console\Commands\OneMoreCommand(),
));
26.8. Re-use console application¶
You are also able to retrieve and re-use the default console application.
Just call ConsoleRunner::createApplication(...)
with an appropriate
HelperSet, like it is described in the configuration section.
<?php
// Retrieve default console application
$cli = ConsoleRunner::createApplication($helperSet);
// Runs console application
$cli->run();