回声功能内部或外部?从自己调用函数?

时间:2012-04-11 14:54:32

标签: php translation

翻译模块

简介

到目前为止,我的代码工作正常,但我不知道这是否是实现我想要的正确方法。我有一个很小的功能来翻译我的网页上的字符串。如果我用一个数字来调用它,它会在一个表中搜索id,只有在它用于该页面时才会显示它。如果我用字符串调用它,它会搜索另一个表中的字符串,如果该字符串不存在,该函数将打印传递的字符串,用带有警告的空格替换“_”。

如果正确实施,有两件事我想知道(如上所述,它们有效,但我不确定它们是不是一个好主意)。但首先是代码。

代码

// Function to output language strings.
function text($Id)
    {
    // Already defined and tested that are valid (sql injection avoided also)
    global $Lang;
    global $FullUrl;

    if (is_int($Id))    // If a number is being passed
        {
        $results = mysql_query("SELECT * FROM translations WHERE id='$Id' AND page='$FullUrl'") or die ('Could not query:' . mysql_error());
        $row = mysql_fetch_assoc($results);
        if (!empty($row[$Lang])) echo $row[$Lang];  // If there is some, echo it
        else error($FullUrl,$Lang); // Else, calls error function
        }

    else    // If a string is being passed
        {
        $results = mysql_query("SELECT * FROM htranslations WHERE keyword='$Id'") or die ('Could not query:' . mysql_error());
        $row = mysql_fetch_assoc($results);
        if (!empty($row[$Lang])) echo $row[$Lang];  // If it exists in the table, echo it
        else    // Else (it doesn't exist)
            {
            $NewId = str_replace("_", " ", $Id);    // Replace the "_" with " "
            echo "<span style='color: red;' title='";   // Set a red color (warning)
            text(Wrong_sentence);   // Call this function and echo "This sentence could be wrong"
            echo "'>".$NewId."</span>"; // Echo the passed string with spaces
            error($FullUrl,$Lang,$Id);
            }
        }
    }

1.在函数内部或外部回声是否更好?

我已经阅读了this个问题,我不打算进一步操纵字符串。所以,从那篇文章来看,我猜测最好的想法就是按照我已经做过的事情,在函数内部回应,但我想知道你对这个特例的看法,因为我还不确定。 返回值并回显该值或从函数中回显它会更好吗?为什么?我的问题主要集中在性能和使代码友好。

2.从函数内部调用此函数是危险的吗?

正如您所看到的,在我撰写text(Wrong_sentence);的最后几行中。我知道你可以从另一个函数调用一个函数,但是你可以调用一个函数来自同一个函数吗?我担心它进入一个无限循环的调用自身,例如,如果table关键字Wrong_sentence被删除或修改。此外,我不知道可能存在的其他安全后果。

欢迎任何其他类型的代码反馈!

2 个答案:

答案 0 :(得分:3)

关注点分离是第一个要照顾的部分。这只是一个必不可少的。

一般来说,你所做的是一个对此有意义的全局函数。它至少应该在视图中可用。虽然我有一些担忧:

  1. 全局:您使用全局变量,就是这样。更糟糕的是,你甚至不检查那里的东西。如果您最终开始使用它们,请确保在使用它们之前检查它们。例如,它可能被覆盖或者造成模糊错误的任何内容。

  2. 关注点分离:此功能除了要求模型提供文本外,其他任何内容都应该做。就是这样。该模型可能返回false / void / error或仅返回文本。处理

  3. 此函数的位置:一般来说,这在MVC术语中称为帮助程序,因此查看帮助程序可能会很有趣。例如在CakePHP中就像这样:http://book.cakephp.org/2.0/en/views/helpers.html这样你就可以用标准的方式设置它的样式,并且你也可以使用标准,这样就可以很容易地找到其他开发人员。如果我看到帮助者,我知道在哪里寻找它,可以在系统的任何位置定义全局函数。

  4. 永不回声:回声不太好,我们更愿意在需要时将它们直接放入视图中。为什么?因为它使调试结果更容易,我们只需要一种方法,但在变量和回声中使用它们。

    echo text(123);

  5. 它不会占用更多代码或其他东西,但它会生成一个标准。例如,如果您需要变量或其他方法:

    echo strtotupper(text(123));
    

    如果您正在测试,则需要相同的功能,您需要该功能的响应。显然,可以测试回声,但回报效果会好得多。

    1. 网址和文字的组合:一段文字属于其他内容。该URL链接到该内容,但似乎不是正确的链接。例如,在URL中获取带有拼写错误的标题的页面。网址已修复,但您的文字已不再关联。

    2. 在一个功能中组合2个功能:当您开始单元测试代码时,您会注意到为什么会产生更多复杂性问题。你有2个函数,getTextById和getTextByKeyword。基本上你已经在这里看到了问题:

      &#34; SELECT * FROM htranslations WHERE keyword =&#39; $ Id&#39;&#34;

    3. 您正在查找似乎是关键字的$ Id。容易出错的代码。选择一种味道并坚持下去。一般来说,我不喜欢硬编码的id,因为他们什么都不说。所以我建议使用类似的东西:

      text('CONTACT_ADDRESS')
      

      这种标签是可读的(这在视图中很重要,而且很有意义。例如一个不好的标签:

      <p><?php text(24234); ?></p>
      <p><?php text(96985); ?></p>
      

      你不知道它是什么。但如果我在视图中写下这一点,那就完全清楚了:

      <p><?php text('ORGANISATION_INTRODUCTION'); ?></p>
      <p><?php text('ORGANISATION_FOUNDERS'); ?></p>
      

      这些是两段文字,但现在你知道哪些文字了。如果您看到页面本身,也知道在哪里可以找到它们。如您所见,这些简单示例使用页面前缀,但显然也可能有全局文本。就像侧边栏中的文字一样。根据您的需求,这里有很多选择。您甚至可以自动添加页面名称等。

      1. 滥用MySQL功能:不再这样做了:

        $ results = mysql_query(&#34; SELECT * FROM htranslations WHERE keyword =&#39; $ Id&#39;&#34;)或死亡(&#39;无法查询:&#39; .mysql_error ());

      2. 只需创建一些PDO语句或其他安全的东西,并确保捕获错误,验证输入等。由于这类问题,已经看到很多黑客。

        1. 已有的解决方案:您不是第一个翻译文本的人。那你为什么不看看已经可用的系统,比如支持多语言或http://www.gnu.org/software/gettext/的Framework。已经有这么多技巧,为什么要开发一个新技巧?

        2. 递归:如果您使用错误的密钥调用您自己的函数以找不到错误,它会一次又一次地调用。只是不太好。将错误处理(这是一个开发错误)拆分为单独的类。这可以解决它自己的错误处理问题。这也是关注点的分离。

        3. 显然,您可以添加更多反馈,但认为这为您提供了一个非常完整的开始,可以重新思考您的方法。不仅有一个好的解决方案,但肯定你可以在第一个概念上有所改进。

答案 1 :(得分:0)

由于第二个问题从其他答案和评论中清楚可见,我将回答第一个问题(尽管我认为回答自己很奇怪,但我找到了一个更适合我的问题的答案)。我可以同时拥有两个,在内部或外部回声。这是代码:

// Function to output language strings.
function text($Id)
    {
    // Already defined and tested that are valid (sql injection avoided also)
    global $Lang;
    global $FullUrl;

    $numargs = func_num_args(); // Get the number of arguments that are being passed.
    if ($numargs == 2)  // If there are actually two
        $Var=func_get_arg(1);   // Set $Var with the second value (1).

    if (is_int($Id))    // If a number is being passed
        {
        $results = mysql_query("SELECT * FROM translations WHERE id='$Id' AND page='$FullUrl'") or die ('Could not query:' . mysql_error());
        $row = mysql_fetch_assoc($results);
        if (!empty($row[$Lang]) && !isset($Var)) echo $row[$Lang];  // If there is some, echo it
    elseif ($Var==1) return $row[$Lang];
        else error($FullUrl,$Lang); // Else, calls error function
        }

    else    // If a string is being passed
        {
        $results = mysql_query("SELECT * FROM htranslations WHERE keyword='$Id'") or die ('Could not query:' . mysql_error());
        $row = mysql_fetch_assoc($results);
        if (!empty($row[$Lang]) && !isset($Var)) echo $row[$Lang];  // If it exists in the table, echo it
        elseif (!empty($row[$Lang]) && isset($Var)) return $row[$Lang];
        else    // Else (it doesn't exist)
            {
            $NewId = str_replace("_", " ", $Id);    // Replace the "_" with " "
            echo "<span style='color: red;' title='";   // Set a red color (warning)
            text(Wrong_sentence);   // Call this function and echo "This sentence could be wrong"
            echo "'>".$NewId."</span>"; // Echo the passed string with spaces
            error($FullUrl,$Lang,$Id);
            }
        }
    }

所以,如果我只想给ECHO写一些文字,我会写tex(56)text(Existing_string)text(Non_existing_string)。但是要将这些相同的文本作为变量返回,我只需要写tex(56,1)text(Existing_string,1)"Non existing string"。请注意,要使用“Non existing string”,我不需要传递它并返回它自己。

该代码仍有许多问题,但正如您所见,我正在学习和改进它。到目前为止,这段代码完全正常。