【问题标题】:How to declare local variable inside a block which is invisible outside the block in PHP?如何在 PHP 中块外不可见的块内声明局部变量?
【发布时间】:2014-11-18 23:55:48
【问题描述】:

我是 PHP 新手,并且已经在 Perl/C/Scheme 方面有一些经验,我觉得我很困扰我 不知道如何在 if/for/while 等块内定义变量,并使其在块外不可见。

我是否必须将代码块内的代码放入函数中才能使其成为本地代码?

例如,我的很多错误都是由这样的代码引起的:

<?php
    for($id = 0; $id<10; $id++)
    {
        $a = $id;
    }
    if(1)
    {
        $b = 3;
    }
    echo $a;//9
    echo $id;//10;
    echo $b;//3
?>

但是,我 perl,这样的代码是安全的:

#!/usr/bin/perl
use 5.014;
use strict;
use warnings;
for(my $id = 0; $id < 10; $id++)
{
    my $a = $id;
}
if(1)
{
    my $b = 3;
}
#say $a; #error
#say $b; #error
#say $id; #error

在 C 中,这样的代码会导致错误(使用 -std=gnu99 编译)

#include<stdio.h>

int main()
{
    for(int i=0; i<10; i++)
    {
        int a = i;
    }
    if(1)
    {
        int b = 3;
    }
    //printf("%d\n",i);//err
    //printf("%d\n",a);//err
    //printf("%d\n",b);//err
    return 0;
}

那么,由于 PHP 缺少块作用域,我该如何避免错误呢?

【问题讨论】:

  • 将你的块切割成函数,让它有一个范围?你能做的最好的就是使用一些解决方法
  • 通过改变您编码时的思维方式:PHP !== Perl && PHP !== C
  • 通过保持你的函数,从而你的范围很小,而不是在你的范围内为不同的目的重用变量名,并在范围的顶部初始化你的变量。
  • 如果您的范围太大以至于您必须搜索多个不同的文件,那么您的范围就太大了。
  • 如果你写的是长的程序脚本,那你就有问题了,要么把它分解成更小的函数,要么遵循 OOP 方法,你不会有这个问题

标签: php


【解决方案1】:

几种可能的方法,但它们几乎都归结为:将代码分解为函数。一种或另一种方式,这一切都回到了这一点。并且不管 PHP 缺乏块作用域,你都应该为可维护和可重用的代码这样做。

  1. 使用方法尽可能小且自包含的类。
  2. 使用尽可能小且独立的函数。
  3. 永远不要使用global
  4. 不要编写冗长的过程代码,无论它是否在函数内。如果范围超过一屏代码,则很可能它太长并且可能被分解。
  5. 使用合理的描述性变量名称,在每个范围的顶部对其进行初始化,并且不要在整个范围内将它们重复用于不同的目的。
  6. 更多地考虑映射操作、迭代器和回调,例如:

    // Look ma, no $i or other superfluous iterator variables!
    $foo = array_map(function ($bar) { return /* something */; }, $baz);
    
    $foo = array_reduce($bar, function ($foo, $baz) { return /* something */; });
    
    $files = new RecursiveIteratorIterator(
        new RecursiveCallbackFilterIterator(
            new RecursiveDirectoryIterator(__DIR__),
            function ($file) { return /* something */; }
        )
    );
    foreach ($files as $file) {
        /* A lot of code that would have gone here is in the
           RecursiveCallbackFilterIterator callback now. */
    }
    

通常,这些天您将看到的最简单的 PHP 代码广泛使用依赖注入 OOP,并且由许多小类和许多小方法组成。这最大限度地提高了代码的可重用性、灵活性并减少了问题。

作为一种丑陋的变通方法,您可以通过模拟 IIFE 的常见 Javascript 实践来人为地引入作用域:

$foo = call_user_func(function () {
    /* your variables here */
    return $result;
});

这可能适用于一次性脚本,这些脚本本质上只是冗长且程序化,但您仍然希望按范围进行隔离。不过,我一般不会真的推荐这种做法。

【讨论】:

    【解决方案2】:

    在每个块的末尾使用unset($var);

    【讨论】:

    • 使用这种方式,我只能确保我的变量不会污染别人的,但我不能确定我的变量不会被其他人污染...
    【解决方案3】:

    这在 PHP 中非常令人讨厌,我个人有很多与此问题相关的错误。

    您可以做到这一点的一种方法是在块的末尾取消设置()变量。所以在你的代码中做类似

    <?php
        for($id = 0; $id<10; $id++)
        {
        $a = $id;
        }
        if(1)
        {
            $b = 3;
            unset($b);
        }
        echo $a;//9
        echo $id;//10;
        echo $b;//unset notice
    ?>
    

    或在使用变量之前将其分配给 null。

    【讨论】:

    • 其实这是我用的方法,if(isset($var)){die("errmsg")}...unset($var)...
    • 你没有使用 unset()
    猜你喜欢
    • 2016-05-19
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多