【问题标题】:Can I override the PHP built-in function echo()?我可以覆盖 PHP 内置函数 echo() 吗?
【发布时间】:2010-02-02 08:38:34
【问题描述】:

我最近查看了我的源代码,发现真是一团糟。

我的php源码:

echo '<h1>Rar<h1>';
echo '<span>Rar</span>';
echo '<p>Rar</p>';

当我查看呈现页面的浏览器源代码时:

<h1>Rar</h1><span>Rar</span><p>Rar</p>

有没有办法让我覆盖 echo 以便每个输出都以换行符结尾,例如

function echo($string)
{
 echo $string . "\r\n";
}

【问题讨论】:

  • 当您想要换行符时?那你会怎么做?
  • "什么时候你不想换行?" --- 使用打印?
  • 恕我直言,HTML 是供浏览器阅读的,而不是供人阅读的。只要您的源代码可读,我就不会担心 HTML 输出。干净的 HTML 输出是锦上添花,如果没有适当的模板或像 Tidy 这样的工具,在任何中等复杂的应用程序中都很难实现。
  • deceze 是对的,HTML 是针对浏览器的。如果您仍然想查看 HTML,我推荐 Firebug。 Firebug 为您提供 HTML 的完整折叠视图,甚至在被 Javascript 更改时更新它。 非常方便。

标签: php


【解决方案1】:

echo 不是函数,而是语言语句。它不能被重新定义。如果您希望美化您的输出标记,请查看Tidy


可以做的是使用 IDE 的搜索/替换方法并将所有 echo 语句替换为 echo PHP_EOL,。这将在任何输出之前附加操作系统特定的换行符。注意 PHP_EOL 后面的逗号,因为它很重要。

您可以像这样使用 echo 输出多个值:

echo 'one', $foo, PHP_EOL,
     'two', $bar, PHP_EOL;

所以不需要在每一行写echo

但是,我同意任何建议使用更专门的方法来分离内容和布局的人,例如使用模板视图或 HereDoc。

此外,拥有漂亮的标记几乎没有什么好处。如果您使用 Firebug 之类的工具来检查 HTML,那么无论标记实际上是什么混乱,您都将拥有正确格式化的标记。此外,在有很多访问者的网站上,您经常会发现标记被缩小,这与您尝试做的相反,仅仅是因为所有这些换行符和制表符都会增加页面的重量,从而导致速度变慢页面加载和增加的流量成本。

【讨论】:

    【解决方案2】:

    您有多种输出 HTML 的可能性。

    您可以使用heredoc 语法:

    $html = <<<EOF
    <h1>Rar<h1>
    <span>Rar</span>
    <p>Rar</p>
    EOF
    echo $hml;
    

    或者(我认为更好的方法),将 HTML 与 PHP 分开。例如。将所有 PHP 逻辑放在文件顶部,将 HTML 放在 PHP 块之后:

    <?php
       // all your PHP goes here
       $foo = 'bar'
    ?>
    <!-- HTML comes here -->
    <html>
      <body>
        <div>Hello <?php echo $foo; ?> </div>
      </body>
    </html>
    

    可以如上所示打印变量。但这些变量包含 HTML。

    当你必须根据条件输出 HTML 时,你可以使用alternative syntax for control statements:

    <?php if($some_condition): ?>
        <h1>Rar<h1>
        <span>Rar</span>
        <p>Rar</p>
    <?php endif ?>
    

    这种方式也更容易调试你的 HTML,因为它不仅仅是一个 PHP 字符串。

    【讨论】:

      【解决方案3】:

      您可以设置和输出缓冲区,然后通过htmltidy 运行缓冲区。整洁的扩展甚至有a specific function 用于此目的。在开始输出 html 之前调用它:

      ob_start('ob_tidyhandler');
      

      【讨论】:

        【解决方案4】:

        虽然此解决方案不会覆盖 echo,但您可以使用换行符获得接近 echo 的内容。添加:

        function e() {
            return o::singleton();
        }
        
        class o {
            private static $instance;
        
            public static function singleton()
            {
                if (!isset(self::$instance)) {
                    $className = __CLASS__;
                    self::$instance = new $className;
                }
                return self::$instance;
            }
        
            public function __set($prop, $txt) {
                echo $txt . PHP_EOL;
            }
        }
        

        到你的文件,然后你可以使用:

        e()->o = "Line which ends in newline";
        

        而不是回声。

        【讨论】:

          【解决方案5】:

          另一种解决方案是使用适当的模板引擎将代码与布局分开。

          【讨论】:

          • @Gordon,我同意。 PHP 可以用作模板引擎。但它并不总是被用作一个。在那些情况下,拥有模板会让生活更简单吗? @Natrium,不是真的。我喜欢它在 Google webapp 和 Django(都是 Python 框架)中完成的方式,并且可以在 PHP 中使用 Smarty 或类似框架来实现。
          • @Srirangan 使用 template 很好,但是在 PHP 之上添加另一个模板 engine 会给您的应用增加无用的膨胀恕我直言。
          • @Gordon 总的来说,我同意,但最近玩过 HAML,我保留了一个例外,即模板引擎将您的 LOC 减少 50%,同时提高可读性和有效性保证。 :)
          • @deceze 性能如何?也增加了吗?另外,您是否在计算时考虑了框架本身的 LOC?如果你想保证有效的输出,你可以只使用 DOM 进行模板化或通过 Tidy 透明地运行输出。
          • @Gordon 我不明白为什么框架的 LOC 很重要,如果它为我节省了大量的打字时间。 “编译”的模板文件也可以很容易地被缓存;无限期地投入生产。
          【解决方案6】:

          您可以像这样使用__toString() magic method 间接重载echo()

          <?php
          class CleanOutput
          {
              public $content;
          
              public function __construct($c) {
                  $this->content= $c;
              }
          
              public function __toString() {
                  return $this->content . '\r\n';
              }
          }
          
          $text= new CleanOutput('Hello world!');
          echo $text;
          ?>
          

          上面会输出“Hello world!”在末尾附加换行符和回车符。有办法进一步封装这一点,但它们超出了我的回答范围。

          编辑
          如前所述,上述解决方案缓慢/笨拙。这是使用output buffering 的更优雅的解决方案:

          <?
          function clean_up($foo) {
             return $foo . '\r\n';
          }
          ob_start('clean_up');
          ob_implicit_flush(true);
          echo "Hello world!";
          ?>
          

          这更快更干净(尽管从技术上讲它不会“覆盖”回声)。

          【讨论】:

          • 绝对正确和巧妙的解决方案。问题是,OP 需要将他当前echoing 的每一段文本包装到new CleanOutput() 中,这错过了问题的重点。 ;-)
          • 这是非常低效的;它需要的时间是 echo/print 等效时间的十倍以上。此外,'\r\n' 不会按预期工作。它必须用双引号括起来。
          • 非常正确(在这两个方面)。 OP询问是否可以覆盖回声。我证明它可以:P
          • 从技术上讲,这不会覆盖echo。只要在字符串上下文中使用对象,就会使用__toString。那是echo,也是print(string)'foo' . $object
          • 第二个解决方案非常简洁!谢谢!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-05
          相关资源
          最近更新 更多