24

是否有任何程序 IDE 可以在 PHP 字符串中格式化 MySQL 代码,例如我使用 PHPStorm IDE,但它不能这样做。

它适用于 PHP 和 MYSQL,但不适用于 php 字符串中的 MYSQL。我已经准备好使用新的 IDE,因为现在我必须手动格式化数百个单行且不可读的数据库请求。我选择的唯一标准是 ide 可以自动执行此操作。

<?php
...
$request1 = "select * from tbl_admin where admin_id= {$_SESSION['admin_id']} and active= 1 order By admin_id Asc";
...
?>

应该成为

<?php
...
$request1 = "SELECT * 
               FROM tbl_admin 
                  WHERE admin_id = {$_SESSION['admin_id']}
                  AND active = 1
                      ORDER BY admin_id ASC";
...
?>
4

17 回答 17

17

在我看来,最好的方法是使用正则表达式或 SED/AWK 来格式化所有内容,它为我们提供了即时替换地图的好处。不过,您可能有代码错误的可能性很高,所以这有点困难。

让我稍微研究一下,看看我能不能想出一个好的解决方案。是否保证您将所有 SQL 封装在双引号中?

编辑

尝试这个

cd {{directory}} && find . -type f -print0 |
  xargs -0 perl -i.bak -pe 's/select/SELECT/g ; s/from/\n\tFROM/g ; s/where/\n\t\tWHERE/g ; s/and/\n\t\tAND/g ; s/order by/\n\t\tORDER BY/g ; s/asc/ASC/g ; s/desc/DESC/g ;'

这是一个例子

$ printf '"select * from whatever where this = that and active = 1 order by something asc";\n' |
> perl -pe 's/select/SELECT/g ; s/from/\n\tFROM/g ; s/where/\n\t\tWHERE/g ; s/and/\n\t\tAND/g ; s/order by/\n\t\tORDER BY/g ; s/asc/ASC/g ; s/desc/DESC/g ;'

"SELECT * 
    FROM whatever 
        WHERE this = that 
        AND active = 1 
        ORDER BY something ASC";

漂亮吗?不,一点也不,它有用吗....是的。

我会尝试创建一个过滤器文件,也许是一个小 bash 程序或其他东西,因为我有时间运行这个热的烂摊子。

编辑

这是一些修改后的代码,看起来更漂亮(排序)

printf '$request1 = "select * from whatever where this = that and active = 1 order by something asc";\n' | 
perl -pe 's/select/SELECT/gi ; s/from/\n  FROM/gi ; s/where/\n    WHERE/gi ; s/and/\n    AND/gi ; s/order by/\n      ORDER BY/gi ; s/asc/ASC/gi ; s/desc/DESC/gi ;' | 
awk 'NR == 1 {pad = length($0)/2; print} NR > 1 {gsub(/\r/,""); printf "%*s%s\n", pad, " ", $0}'

__OUTPUTS__
$request1 = "SELECT * 
             FROM whatever 
               WHERE this = that 
               AND active = 1 
                 ORDER BY something ASC";
于 2012-06-20T16:33:51.080 回答
13

据我所知,PhpStorm 可以做到,如果你使用 heredoc 语法

$request1 = <<<SQL
   SELECT * 
           FROM tbl_admin 
              WHERE admin_id = {$_SESSION['admin_id']}
              AND active = 1
                  ORDER BY admin_id ASC
SQL;
于 2012-06-12T21:42:50.343 回答
5

答案是不。

作为替代解决方案,我可以建议将文本(*.php 文件中的所有 PHP 代码)复制到Heidisql的查询编辑器中,单击重新格式化并复制回 NetBeans 并按 Alt+Shift+F。这将格式化 sql 并在之后格式化 php 代码,保留 sql 格式。因此,您不是在使用插件,而是在复制、格式化整个文件、复制回来并再次格式化。

您可以使用此工具代替 HeidiSQL,如果您对此类 Web 工具感到满意,该工具专注于格式化。

如果您想要更多的自动化,您可以使用 netbeans 的正则表达式支持来格式化与反斜杠 n = \n 的新行之前的每个“插入、更新、删除、选择、位置和值”术语运行这 6 次将替换所有“插入” <- 空白加插入,在您的项目中使用新行。您可以编写一个正则表达式来搜索所有“空白加保留字”组合并将它们替换为新行。

您也可以使用它,例如搜索“insert”并替换为“\n\t insert”,这将创建一个新行和一个选项卡

在此处输入图像描述

于 2012-06-20T10:28:47.873 回答
4

由于您的问题是格式化现有代码体,因此您不需要 IDE。您需要一个脚本来批处理所有文件一次,然后您就可以忘记它。这是脚本需要做的:

  1. 正确解析PHP字符串,包括带有各种嵌入或转义引号的字符串。这应该是防弹的,并且应该只关心 PHP 语法。
  2. 使用检测 SQL 命令的算法检查每个 PHP 字符串。这可以根据您的需要变得聪明(例如,无需盲目地接受每个包含单词“insert”的字符串)。
  3. 通过 SQL 漂亮打印机提供已识别的字符串。
  4. 编辑输入文件,用格式化字符串替换原始文件。

理想情况下,第 1 部分和第 3 部分应由现成的模块处理。其余的应该很容易自己组装,对吧?

更新:解释这听起来很简单,我决定自己做。这是一个快速的解决方案。它在 python 中,但如果你愿意切换 IDE,你可以处理安装 python,对吗?

将任意数量的 php 文件拖放到脚本上,或从命令行调用它,它将通过@Parahat 建议的SQLFormat API过滤 SQL 位。它会在原地编辑文件,因此请保留一份副本!

"""Format sql strings embedded in php code, editing source IN PLACE"""
import sys, re, urllib, urllib2

def processfile(fname):
    with open(fname) as fp:
        text = fp.read()

    with open(fname, "w") as out:
        for token in chunk(text):
            if is_sql_string(token):
                token = token[0] + sqlformat(token[1:-1]) + token[0]
            out.write(token)

def sqlformat(query):
    sqlapi = 'http://sqlformat.appspot.com/format/?keyword_case=upper&reindent=1&n_indents=4&'
    return urllib2.urlopen(sqlapi+urllib.urlencode({'data':query})).read()

php_mode = False # global, so that is_sql_string() can examine it
def chunk(src):
    """Chunk the php file into interesting units"""
    global php_mode
    while src:
        if not php_mode: # Read up to the next php group, if any
            m = re.match(r".*?<\?php", src, re.S)
            if m:
                tok, src = _usematch(m, src)
                yield tok
                php_mode = True
            else: # No more php groups: EOF
                yield src
                return

        else:  # Reading php code
            # PHP ends without another string?
            m = re.match(r"[^'\"]*?\?>", src, re.S)
            if m:
                tok, src = _usematch(m, src)
                yield tok
                php_mode = False
                continue

            # at non-string material?
            m = re.match(r"[^'\"]+", src) 
            if m:
                tok, src = _usematch(m, src)
                yield tok
                continue

            # Parse a string: Smallest quote-delimited sequence,
            # where closing quote is not preceded by backslash
            m = re.match(r'".*?(?<!\\)"|' + r"'.*?(?<!\\)'", src, re.S)
            if m:
                tok, src = _usematch(m, src)
                yield tok
                continue

            # Something I can't parse: advance one char and hope for the best
            tok, src = src[0], src[1:]
            yield tok

def _usematch(m, inp):
    return m.group(), inp[m.end():] # Matched chunk & remaining input

# To recognize an sql command, it MUST begin with one of these words
sql_commands = set("select insert update delete create drop alter declare".split())
def is_sql_string(tok):
    if not php_mode or len(tok) < 3 or tok[0] not in set("\"'"):
        return False    
    tokwords = tok[1:-1].split()
    return tokwords and tokwords[0].lower() in sql_commands

for fname in sys.argv[1:]:
    processfile(fname)
于 2012-06-22T23:01:22.787 回答
4

考虑到这个问题:是否有一个IDE会自动格式化sql查询,我必须同意ugurcode。答案很简单:没有。并且有充分的理由。

基本上,SQL 查询只不过是任何 IDE 中的字符串。由于字符串可以包含有意的空格和制表符,如果 IDE 重新格式化字符串内容,那将是非常糟糕的。

适用于任何 IDE 的唯一选项是在字符串的开头检测 INSERT、UPDATE、DELETE,然后格式化字符串的其余部分。当然,它也会尝试对显示“插入引号”的字符串执行相同操作这里..”,这又是一件坏事。

因为我不想让你一无所有,所以我会就一个好的 IDE 给你建议,让你选择哪个实际上可以进行正确的代码格式化、代码完成、良好的缩进、插件等。基本上是 php 的最佳 IDE开发(至少它是我多年专业 php 开发中发现的最好的)。

Netbeans 将是您的首选 IDE。它比 Eclipse/PHP 更快,比 codelobster 等更稳定。

于 2012-06-22T10:06:21.963 回答
4

在 PHPStorm 中,您可以为您的项目指定 SQL 方言:http: //www.jetbrains.com/phpstorm/webhelp/sql-dialects.html

接下来,您必须设置数据源: http: //www.jetbrains.com/phpstorm/webhelp/data-sources-2.html

之后,您的 IDE 将支持表(字段)的 SQL 语法和自动完成功能。


此外,还有一个页面,您可以在其中指定 SQL 代码样式: http: //www.jetbrains.com/phpstorm/webhelp/code-style-sql.html

于 2012-06-26T20:38:24.437 回答
4
  1. 记录、分析您的 SQL 语句。
  2. 使用一个外部服务,比如这个 - SQLFormat API - 来格式化你的 SQL 语句
  3. 您也可以在下载 Python 源代码的机器上运行它。
于 2012-06-21T21:12:15.990 回答
2

我总是使用SQLyog来格式化我的 SQL 语句并将它们粘贴回 IDE,因为我也没有找到能够在 php 块中格式化 sql 的 IDE。

于 2012-06-25T09:05:37.657 回答
2

没有这样的IDE。也许某些 SQL 被分解为多个字符串连接,或者某些 SQL 是使用某个迭代器生成的。或者它可能包含无效的 SQL,例如{$_SESSION['admin_id']}.

您唯一的机会是编写一个小脚本,调整以匹配编码风格和可能的无效 SQL 内容,这将修复所有应用程序源代码文件。你需要几个小时才能把它弄好,但最终你将不需要一个不存在的 IDE,你将拥有一个漂亮的僵化 SQL 和更好的源代码。

(以上是一个解决方案,认为您在整个应用程序中有数百条 SQL 语句;如果没有,则只需手动修复它们)。

编辑:确保将所有更改记录在比较表中,以便您可以查看脚本格式化的所有内容。

于 2012-06-19T23:28:44.803 回答
2

在 MySQL Workbench 中编写查询,然后编辑->格式->美化查询

然后将查询粘贴到 netbeans 中,选择测试和选项卡。

于 2012-06-21T16:32:21.480 回答
2

可能是 nuSphere 调试器以某种方式帮助您执行此操作这里是链接nuSphere

于 2012-06-20T10:51:16.143 回答
1

您可以使用tokenizer扩展来编写格式化 SQL 的脚本。

可以从命令行调用以下脚本,它从标准输入读取并写入标准输出。它处理两种引用样式(双引号或单引号)。

根据起始词扫描所有字符串以查找可能的 SQL 语法,并在每个关键字之前插入换行符;起始词和关键字都是可扩展的,所以去狂野吧:)

<?php

$tokens = token_get_all(file_get_contents('php://stdin'));

function token_value($token)
{
        return is_array($token) ? $token[1] : $token;
}

function sql_format($s)
{
        if (preg_match("/^(?:select|insert|update|delete)/i", $s)) {
                // prefix newline and tab before every keyword
                return preg_replace('/\b(from|where|and|order|group by)/i', "\n\t\\0", $s);
        }
        return $s;
}

$target = '';
$i = 0; $n = count($tokens);
while ($i < $n) {
        $token = $tokens[$i];
        if ($token === '"') {
                $s = ''; ++$i;
                while ($i < $n && $tokens[$i] !== '"') {
                        $s .= token_value($tokens[$i]);
                        ++$i;
                }
                if ($i < $n) {
                        ++$i;
                }
                $target .= '"' . sql_format($s) . '"';
        } elseif (is_array($token) && $token[0] === T_CONSTANT_ENCAPSED_STRING) {
                $quote_style = $token[1][0];
                $target .= $quote_style . sql_format(trim($token[1], "'\"")) . $quote_style;
                ++$i;
        } else {
                $target .= token_value($token);
                ++$i;
        }
}

echo $target;
于 2012-06-25T08:10:27.463 回答
1

我为 MS SQL Server 和 C# 代码构建了一个工具来执行此操作。我很乐意为此目的更改工具,但需要支付少量费用。 http://www.softfrontiers.com/Downloads/ReIndenter.shtml

我的一两个小时的时间将为您节省许多小时的挫败感。

于 2012-06-24T08:26:40.517 回答
1

您问:

是否有任何程序IDE可以在PHP字符串中格式化MySQL代码

特别是这个 PHP 字符串定义:

$request1 = "select * from tbl_admin where admin_id= {$_SESSION['admin_id']} and active= 1 order By admin_id Asc";

答案是否定的。IDE 中的 PHP 解析器或运行 PHP 的token_get_all.

首先,token_get_all您应该能够提取对您的情况有意义的部分进行编辑。这里有上下文:

<309:T_VARIABLE> "$request1" <371:T_WHITESPACE> " " "=" <371:T_WHITESPACE> " " """ <314:T_ENCAPSED_AND_WHITESPACE> "select * from tbl_admin where admin_id= " <375:T_CURLY_OPEN> "{" <309:T_VARIABLE> "$_SESSION" "[" <315:T_CONSTANT_ENCAPSED_STRING> "'admin_id'" "]" "}" <314:T_ENCAPSED_AND_WHITESPACE> " and active= 1 order By admin_id Asc" """ ";"

正如这些标记所示,有很多额外的工作要从中提取你所说的字符串:

$request1 = "select * from tbl_admin where admin_id= {$_SESSION['admin_id']} and active= 1 order By admin_id Asc"

这需要在令牌中进行管理和标识:

<314:T_ENCAPSED_AND_WHITESPACE> "select * from tbl_admin where admin_id= " <375:T_CURLY_OPEN> "{" <309:T_VARIABLE> "$_SESSION" "[" <315:T_CONSTANT_ENCAPSED_STRING> "'admin_id'" "]" "}" <314:T_ENCAPSED_AND_WHITESPACE> " and active= 1 order By admin_id Asc"

如本例所示,这不是真正的 SQL。因此,您不仅需要找到一个 SQL 解析器(它存在于 PHP 中,请参阅Parsing sql query PHP),而且您还需要让该 SQL 解析器知道 PHP 变量替换,就像{$_SESSION['admin_id']}您的情况一样。对你来说它是一个变量,对于 SQL 解析器来说,如果不是错误的话,这只是一个怪异的语法汤。

您的小代码示例是一个很好的示例:它已经表明没有关于将被替换的字符串的性质的信息。由于此信息被隐藏,SQL 解析器将永远无法将此字符串视为格式正确的内容。

所以为了让我的回答“不”更深刻:因为没有关于如何在高级语言级别处理多个结果的通用工具(PHP 字符串在 SQL 中有多个可能正确的表示,只有变量内容的作者才能知道哪个一个是正​​确的)已经存在,没有可用的通用解决方案。

您可能只想在您的代码库中启动一些正则表达式,然后将您感到满意的结果一起闪电战,并且确实值得考虑使用ehime排队的工具。

但可能值得花时间并首先从 PHP 令牌流中提取字符串,重新格式化字符串,然后继续输出结果。这是 perl 和正则表达式不能给你的东西,因为它们没有 PHP 标记器。

于 2012-06-26T10:47:47.890 回答
0

如果所有许多 IDE 都不支持这样的事情,那么在大多数情况下是有原因的。请考虑为您的工作准备好的语句或对象包装器。我知道这两件事不能在几分钟内在每个系统中实现,但是您的代码将变得可维护。

简而言之:IDE 无法纠正设计错误。他们只是让他们看起来漂亮和有色。

于 2012-06-26T21:16:33.563 回答
0

我用过 PHPDesigner。我认为这将满足您的期望。

于 2012-10-09T09:36:13.220 回答
0

派对迟到了,但是...

function formatSQL($txt){
    $txt = str_replace('SELECT ', "\nSELECT", $txt);
    $txt = str_replace(' MATCH', "\nMATCH", $txt);
    $txt = str_replace(' AGAINST', "\nAGAINST", $txt);
    $txt = str_replace(' OR ', "\nOR", $txt);
    $txt = str_replace(' AND ', "\n\tAND ", $txt);
    $txt = str_replace(' FROM ', "\nFROM", $txt);
    $txt = str_replace(' WHERE ', "\nWHERE", $txt);
    $txt = str_replace(' ORDER ', "\nORDER", $txt);
    return $txt;
}
于 2021-11-01T09:12:12.587 回答