在PHP中使用花括号来组织代码结构

26

在PHP中,是否可以使用大括号将代码片段包裹起来(而不使用该片段作为函数)?

以下代码是否与不使用大括号的代码表现相同?或者可能会根据括号内外使用的代码类型而出现任何问题吗?

例如,下面这个代码会如何表现:

<?php

// First Code-Block
{# several lines of code
}

// Second Code-Block
{# another several lines of code
}

?>

始终保持这种行为:

<?php

// First Code-Block
# several lines of code

// Second Code-Block
# another several lines of code

?>

更新: 正如"My1"的评论中所述,其中一个目标是对大型代码部分进行结构化。尤其是因为大多数IDE都提供了在括号之间折叠行的选项。

考虑到"dragondreamer"和"Luke Mills"的答案,我进行了一些尝试,到目前为止我没有遇到任何副作用。当然,随着未来PHP版本的更新,情况可能会有所改变,但"Luke Mills"的答案提供了关注点的良好指引。


你的意思是,没有像 if(true) { ... } 这样的东西吗?为了什么目的? - quietmint
我非常希望看到这个实现一种方式,让我们通过包装可以安全回收的代码部分来管理垃圾收集,一旦段/语句完成就可以进行回收。 - superhero
4
当你有大段代码需要滚动查看时,拥有一个能够"折叠"代码块的编辑器会非常有帮助,因为随着时间推移,滚动变得很麻烦,而这样的功能可以让你更轻松地专注于当前正在编写的代码。 - My1
4个回答

35

是的,但它不会创建新的本地作用域。这通常不是常规操作。通常情况下,人们会使用注释来标记这样的块。

更新:

花了一些时间才在手册中找到对它的引用,但在这里:

http://www.php.net/manual/en/control-structures.intro.php

任何 PHP 脚本都是由一系列语句构建而成的。语句可以是赋值、函数调用、循环、条件语句甚至是一个什么也不做的语句(空语句)。语句通常以分号结束。此外,语句还可以通过用大括号封装一组语句来将语句分组为语句组。语句组本身也是一种语句。本章介绍了各种语句类型。

关键在于语句可以通过用大括号封装一组语句来将语句分组为语句组

我还查找了与这种情况相关的变量作用域的参考资料,但手册没有明确提到它,不过您可以像这样考虑:

在 PHP 中,函数和类创建一个变量作用域。您可以在此处阅读有关该主题的内容:http://php.net/manual/en/language.variables.scope.php。但是,语句组(如上所述)并不会。不要像将函数(或类)封装括号一样考虑语句组(花括号),而是将它们视为控制结构(ifforwhileswitch 等)的语句组的花括号 - 因为它们正是这样。如果您正在使用 if 语句(或任何其他控制结构),那么很明显大括号不会引入新的作用域,它们只是语句块的包装器。


5
理由:我必须使用一个具有本地设置的代码编辑器(notepad ++),它只能折叠注释块(*/ /*)和功能块({})。 - Albin
5
@Stackoverflow2000说:“所有的理由中,‘这样我就可以在我的编辑器中使用代码折叠’,一定是最糟糕的一个……” - prodigitalson
1
@Luke Mills:谢谢,我从没想过去看“介绍”,我以为花括号会有自己的规范,所以我试图在命令参考中找到它们作为一个独立条目。 - Albin
12
@prodigitalson,如果你不使用代码折叠,那么我认为这是一个“不好的理由”。但是,如果你需要它而无法选择你的编辑器,那么拥有一种替代方案就很重要。(附注:只要你不提供帮我完成工作的服务,请不要用适用于你 个人 工作的标准来评判我的理由) - Albin
5
值得一提的是,在来这里之前,我自己尝试了一下,因为我认为这可能对解决不能嵌套的 /* */ 样式注释问题很有用。使用花括号可以定义一个代码块并在顶部放置注释。所有的 IDE 都会让你找到给定括号对,这样就容易找到注释不再适用的位置,而不是像嵌套注释块那样难以解析的 /* ENDS */ 或类似的东西。我认为出于这个原因它很有用。 - ThisLeeNoble
显示剩余5条评论

11

如果您将PHP代码用花括号括起来,其行为不会改变。但是,您不能在花括号内使用某些PHP语句:

  • namespace 声明;
  • 命名空间 use 声明用于别名或导入任何名称;
  • 全局 const 声明;
  • __halt_compiler()

这意味着以下脚本将正常工作:

<?php
const x = 5;
echo x;

但以下代码将无法编译:

<?php
{
  const x = 5;
  echo x;
}

5
在我正在处理的一个项目中,我使用语句组来表示结构 - 在我的情况下,路由器中创建的节点之间的父/子关系:
$router = new Router();

$admin = $router->route('admin');
{
    $upload = $admin->route('upload')->post('upload');

    $menu = $admin->route('menu');
    {
        $menu->route('load')->get('load');
        $menu->route('save')->get('save');
    }
}

内部,它构建了一个分层结构,类似于:

/admin
  /upload
  /menu
    /load
    /save

在这个例子中调用route()会创建一个子级 - 所以代码会创建一个具有树形结构的模型(在路由器内部),但代码的结构并不反映这一点。
我在这里使用花括号使代码更易读,因为如果没有花括号和缩进,阅读代码将会相当困难。
$router = new Router();

$admin = $router->route('admin');
$upload = $admin->route('upload')->post('upload');
$menu = $admin->route('menu');
$menu->route('load')->get('load');
$menu->route('save')->get('save');

在这种情况下,缩进确实可以更清楚地说明正在发生的事情。


1

我这样做纯粹是因为我的文本编辑器(Komodo Edit 8.5)。如果它能够帮助你,不会造成任何问题,并且没有其他更简单的方法来解决问题,那么这并不是“坏原因”或“糟糕的编码”。

我通过一个解决方案来解决这个问题:

if(1 == 1){ //always executing if function
//whatever you want to add
}
#

在大括号末尾添加 # 可以防止我的编辑器折叠所有空行。这有助于进一步结构化代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接