2017-08-02 66 views
1

我建立以化合物的形式与table_name和将用于随后建立的时态数据库表column_name领域的集合。但是经常我会收到重要电子邮件日志与此错误:验证字段名阿恩MySQL的保留字

[42000][1064] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHECK' at line 1

这看起来当用户写无论是表名或列名作为MySQL的一个保留字像CREATE TABLE语句失败。

因此,我会创建一个回调验证器来避免这种关键字,然后再保存表名和列。这是我的方法到目前为止:

public function validTableName($name) 
{ 
    try { 
     $this->em->getConnection()->executeQuery('SELECT TRUE AS '.$name); 
    } catch (\Exception $except) { 
     return true; 
    } 

    return false; 
} 

它工作正常,但它是完全不安全的,并倾向于SQL注入。我一直很想复制的MySQL的保留字的完整列表,但它并没有感觉就很好的选择,我...

有一个简单的办法知道一个名字是一个MySQL的保留字或不?

+0

你能只需在表格创建脚本中添加反引号,以便不必担心保留字? – JNevill

+0

您可能已经开放SQL注入与创建方法,没有? – chris85

回答

1

周围使用表名和列名引号(')应该足以避免这种错误。但是,如果你真的想验证它..你可以使用Doctrine DBAL层做,在安全,没有任何查询:

public function isReservedWord($name) 
{ 
    // Returns the keyword list instance of this platform. 
    $keywordList = $this->em 
     ->getConnection() 
     ->getSchemaManager() 
     ->getDatabasePlatform() 
     ->getReservedKeywordsList(); 

    // Checks if the given word is a keyword of this dialect/vendor platform. 
    return $keywordList->isKeyword($name); 
} 

这一个已经可以支持多种平台:

'mysql'   => 'Doctrine\DBAL\Platforms\Keywords\MySQLKeywords', 
'mysql57'  => 'Doctrine\DBAL\Platforms\Keywords\MySQL57Keywords', 
'sqlserver'  => 'Doctrine\DBAL\Platforms\Keywords\SQLServerKeywords', 
'sqlserver2005' => 'Doctrine\DBAL\Platforms\Keywords\SQLServer2005Keywords', 
'sqlserver2008' => 'Doctrine\DBAL\Platforms\Keywords\SQLServer2008Keywords', 
'sqlserver2012' => 'Doctrine\DBAL\Platforms\Keywords\SQLServer2012Keywords', 
'sqlite'  => 'Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords', 
'pgsql'   => 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords', 
'pgsql91'  => 'Doctrine\DBAL\Platforms\Keywords\PostgreSQL91Keywords', 
'pgsql92'  => 'Doctrine\DBAL\Platforms\Keywords\PostgreSQL92Keywords', 
'oracle'  => 'Doctrine\DBAL\Platforms\Keywords\OracleKeywords', 
'db2'   => 'Doctrine\DBAL\Platforms\Keywords\DB2Keywords', 
'sqlanywhere' => 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhereKeywords', 
'sqlanywhere11' => 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhere11Keywords', 
'sqlanywhere12' => 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhere12Keywords', 
'sqlanywhere16' => 'Doctrine\DBAL\Platforms\Keywords\SQLAnywhere16Keywords', 
+1

哦,我明白了......我会试试这个,我想这是一个抽象的解决方案?即仅与MySql无关? – presto

+0

是的,我的答案更新与支持的平台列表 – yceruto

0

只需插入全部来自this link的话到一个新表,做一个查找表上的1 ..

+0

...假设OP使用5.7。此外,如果他们升级/降级,这可能无法正常工作。 – chris85