如何在PHP中的块外部不可见的块内声明局部变量?

时间:2014-09-24 13:06:57

标签: php

我是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
?>

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

#!/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缺少块范围?

3 个答案:

答案 0 :(得分:2)

有几种可能的方法,但它们几乎可以归结为:将代码分解为函数。这一切都回归到了这一切。无论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. */
    }
    
  7. 通常,您现在看到的最安全的PHP代码会广泛使用依赖注入OOP,并且包含许多具有许多小方法的小类。这最大化了代码的可重用性,灵活性并减少了问题。

    作为一种丑陋的黑客攻击,你可以通过模仿IIFE的常见Javascript实践来人为地引入范围:

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

这在PHP中很烦人,而且我个人遇到了很多与此问题有关的错误。

你可以做的一种方法是在块的末尾unset()变量。所以在您的代码中执行类似

的操作
<?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赋值给变量。