Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generate Symfony 4 entities + repositories from existing database
<?php
include './vendor/autoload.php';
$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__);
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__);
$classLoader->register();
class RepoGen extends Doctrine\ORM\Tools\EntityRepositoryGenerator {
protected static $_template =
'<?php
namespace App\Repository;
use App\Entity\__ENTITY__;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
* @method __ENTITY__|null find($id, $lockMode = null, $lockVersion = null)
* @method __ENTITY__|null findOneBy(array $criteria, array $orderBy = null)
* @method __ENTITY__[] findAll()
* @method __ENTITY__[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class __ENTITY__Repository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, __ENTITY__::class);
}
/*
public function findBySomething($value)
{
return $this->createQueryBuilder(\'g\')
->where(\'g.something = :value\')->setParameter(\'value\', $value)
->orderBy(\'g.id\', \'ASC\')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/
}
';
protected $entity = '__Entity';
public function generateEntityRepositoryClass($fullClassName) {
$val = str_replace('__ENTITY__', $this->entity, self::$_template);
return $val;
}
public function setEntityName($name) {
$this->entity = $name;
}
}
// config
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver(__DIR__ . '/Entities'));
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');
$connectionParams = array(
'driver' => 'pdo_mysql',
'host' => 'localhost',
'port' => '3306',
'user' => 'root',
'password' => 'root',
'dbname' => 'dbname',
'charset' => 'utf8',
);
$em = \Doctrine\ORM\EntityManager::create($connectionParams, $config);
// custom datatypes (not mapped for reverse engineering)
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('set', 'string');
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
// fetch metadata
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$em->getConnection()->getSchemaManager()
);
$driver->setNamespace('App\Entity\\');
$em->getConfiguration()->setMetadataDriverImpl($driver);
$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory($em);
$cmf->setEntityManager($em);
$classes = $driver->getAllClassNames();
$metadata = $cmf->getAllMetadata();
foreach ($metadata as $md) {
$md->setCustomRepositoryClass(str_replace('App\Entity\\', 'App\Repository\\', $md->getName().'Repository'));
}
$generator = new Doctrine\ORM\Tools\EntityGenerator();
$generator->setUpdateEntityIfExists(true);
$generator->setGenerateStubMethods(true);
$generator->setGenerateAnnotations(true);
$generator->generate($metadata, __DIR__ . '/Entities');
$repGenerator = new RepoGen();
foreach ($classes as $className) {
$className = str_replace('App\Entity\\', '', $className);
$repGenerator->setEntityName($className);
$repGenerator->writeEntityRepositoryClass($className.'Repository',__DIR__ . '/Repositories');
}
print 'Done!';
@dwgebler

This comment has been minimized.

Copy link
Owner Author

@dwgebler dwgebler commented Apr 5, 2018

Full credit to https://gist.github.com/tawfekov/4079388 @tawfekov
this is just a modification of their gist to include repos for Symfony 4 projects

@MaximeC64

This comment has been minimized.

Copy link

@MaximeC64 MaximeC64 commented Apr 13, 2018

Hello dwgebler,
I search a system to import a existing database for a while so thanks for your job.
But i'm a beginner and i don't know where i have to put this .php file ?
Somebody can help me please ?

Thanks.
Sorry for my english, i'm french.

@dwgebler

This comment has been minimized.

Copy link
Owner Author

@dwgebler dwgebler commented Apr 16, 2018

Hi @MaximeC64 just put the file in the root of your Symfony 4 project where .env, composer.json etc. sit and run from the command line.

@dwgebler

This comment has been minimized.

Copy link
Owner Author

@dwgebler dwgebler commented Apr 16, 2018

Please bear in mind this is just a helper as a starting point when you're by necessity working with an existing database; generating entities from an existing database is not actually a very good idea, since you are importing design flaws from the start rather than starting by building your entities correctly from the ground up. The generated entities will get about 90% of your basic field types and mappings correct, but you'll need to work on them manually to get the right Doctrine ORM structure for your project.

@Neurozone

This comment has been minimized.

Copy link

@Neurozone Neurozone commented Feb 6, 2019

Please bear in mind this is just a helper as a starting point when you're by necessity working with an existing database; generating entities from an existing database is not actually a very good idea, since you are importing design flaws from the start rather than starting by building your entities correctly from the ground up. The generated entities will get about 90% of your basic field types and mappings correct, but you'll need to work on them manually to get the right Doctrine ORM structure for your project.

I just found your work (very good) and as a former dba, I can assure you that the design flow you're feared of came only from developpement team.
I've designed many databases in the past and every flaws came from dev too fierce to ask help from dbas ^^

But thank you for the code ;)

@0x3vil

This comment has been minimized.

Copy link

@0x3vil 0x3vil commented Mar 14, 2020

Thank you so much , this script saved me a ton of effort

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.