2012-05-06 11 views
34

¿Hay alguna forma de citar automáticamente palabras reservadas con Doctrine 2 cuando usa $entityManager->find('entity', id)?Cita automática de palabras reservadas con Doctrine 2

Al usar el generador de consultas, esto se puede hacer, pero debe haber una configuración de configuración global que haga esto? No quiero tener que especificarlo en las anotaciones de las palabras reservadas.

Respuesta

57

Esto fue un problema que planteé hace un tiempo con el equipo de Doctrine.

https://github.com/doctrine/doctrine2/issues/2409

El billete se cerró con el comentario:

Tienes que escapar manualmente caracteres con @Column (name = "` integer`")

así que supongo tendría que tratar con cualquier palabra clave reservada en sus anotaciones

+0

Acabo de descubrir que la doctrina DBAL se envía ahora con la herramienta cli \ Doctrine \ DBAL \ Tools \ Console \ Comma nd \ ReservedWordsCommand() que es realmente útil para escanear sus Entidades por cualquier cosa que pueda causar un problema. Intenta ejecutar "doctrine dbal: reserved-words" para probarlo. –

+5

+1 Parece extraño que la creación de la tabla funcione bien. –

+6

La doctrina de mi humilde opinión está rota aquí. En cualquier otro lugar donde el sistema no escape cosas para usted, se llamaría una vulnerabilidad de inyección SQL. – rjmunro

3

4,6. Citando palabras reservadas

A veces es necesario citar un nombre de columna o tabla debido a conflictos de palabras reservadas. Doctrine no cita identificadores de forma automática, ya que genera más problemas de los que resolvería. Las tablas de citas y los nombres de columnas deben hacerse explícitamente usando tics en la definición.

<?php 
/** @Column(name="`number`", type="integer") */ 
private $number; 

Doctrina entonces citar este nombre de columna en todas las sentencias SQL de acuerdo a la plataforma de base de datos utilizada.

Las citas del identificador no funcionan para unir los nombres de las columnas o los nombres de las columnas del discriminador, a menos que esté utilizando una estrategia personalizada de QuoteStrategy.

Para obtener más control sobre la columna, se introdujo la interfaz Doctrine\ORM\Mapping\QuoteStrategy en 2.3. Se invoca para cada columna, tabla, alias y otros nombres de SQL. Puede implementar QuoteStrategy y configurarlo llamando al Doctrine\ORM\Configuration#setQuoteStrategy().

Se agregó la estrategia de cotizaciones ANSI, que supone que no es necesario citar ningún nombre de SQL. Se puede utilizar con el siguiente código:

<?php 
use Doctrine\ORM\Mapping\AnsiQuoteStrategy; 

$configuration->setQuoteStrategy(new AnsiQuoteStrategy()); 

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#quoting-reserved-words

0

No es implementado por Doctrina simplemente porque es demasiado plataforma de función.

Todo lo que necesita es implementar su propio QuoteStrategy.

Por ejemplo, para el proyecto Symfony:


Copiar y pegar proveedor AnsiQuoteStrategy clase, cambie su nombre y hacer algo de citar:

AppBundle/ORM/QuoteStrategy.php

namespace AppBundle\ORM; 

use Doctrine\DBAL\Platforms\AbstractPlatform; 
use Doctrine\ORM\Mapping as M; 

class QuoteStrategy implements M\QuoteStrategy 
{ 
    private function quote($token, AbstractPlatform $platform) 
    { 
    // implement your quote strategy 
    switch ($platform->getName()) { 
     case 'mysql': 
     default: 
     return '`' . $token . '`'; 
    } 
    } 

    // add quoting to appropriate methods 
    public function getColumnName($fieldName, M\ClassMetadata $class, AbstractPlatform $platform) 
    { 
    return $this->quote($class->fieldMappings[$fieldName]['columnName'], $platform); 
    } 
    // ... Rest methods 
} 

A continuación, registre su estrategia de cotización como un servicio:

src/AppBundle/Resources/config/services.yml

app.orm.quote_strategy: 
    class: AppBundle\ORM\QuoteStrategy 
    public: false 

A continuación, utilizarlo para su configuración EntityManager:
app/config/config.yml

orm: 
    entity_managers: 
    default: 
     quote_strategy: app.orm.quote_strategy 

Eso es todo :)