代码之家  ›  专栏  ›  技术社区  ›  Aaron Yodaiken

在PHP中直接使用超全局变量是好是坏?

  •  8
  • Aaron Yodaiken  · 技术社区  · 14 年前

    所以,我并不是来自一个庞大的PHP背景,我想知道在格式良好的代码中,是否应该直接使用“superglobals”,例如在一些函数的中间,比如说 $_SESSION['x'] = 'y';

    class Doer {
        private $sess;
        public function __construct(&$sess) {
            $this->sess =& $sess;
        }
    } 
    
    $doer = new Doer($_SESSION);
    

    然后使用 Doer->sess 来自实干家内部的版本等等(这种方法的优点是它清楚地表明 Doer

    对于这个问题,公认的PHP设计方法是什么?

    5 回复  |  直到 14 年前
        1
  •  13
  •   grossvogel    14 年前

    $_SESSION $_POST , $_GET ,和 $_COOKIE 进入OOP结构。

    我使用这个方法来集中处理卫生和验证的代码,所有这些都是必要的 isset () 支票,临时支票, setcookie

    强制使用这种结构可能很困难,特别是在有多个编码器的情况下。与 , $\邮政 ,和 $\饼干

    $\u会话


    $post = Post::load ();  
    $post->numeric ('member_age');  
    $post->email ('member_email');
    $post->match ('/regex/','member_field');
    $post->required ('member_first_name','member_email');
    $post->inSet ('member_status',array('unemployed','retired','part-time','full-time'));
    $post->money ('member_salary');
    $post->register ('member_last_name'); // no specific requirements, but we want access
    if ($post->isValid())
    {
      // do good stuff
      $firstName = $post->member_first_name;
    }
    else
    {
      // do error stuff
    }
    

    $\邮政 在调用验证方法时,使用magic命令将它们作为属性返回 __get 方法。失败的字段不能以这种方式访问。我的验证方法(除了 required )不要在空字段上失败,它们中的许多都使用 func_get_args 允许他们同时在多个领域进行操作。一些方法(如 money )自动将数据转换为自定义值类型。

    一种改进的方法是将验证信息存储在一个表单类中,该类用于呈现表单和增强客户端验证,并在提交后清除数据。

        2
  •  4
  •   Marc B    14 年前

    修改超球体的内容被认为是不好的做法。虽然没有什么真正的问题,特别是如果代码是100%在你的控制下,它可能会导致意想不到的副作用,特别是当你考虑混合源代码。例如,如果你这样做:

    $_POST['someval'] = mysql_real_escape_string($_POST['someval']);
    

    $_REQUEST['someval'] 将保持不变,仍然是原来的“不安全”版本。如果您在$\u POST上执行所有转义操作,但稍后的库使用$\u请求并假定它已经转义,则这可能会导致意外的注入漏洞。

    因此,即使可以修改它们,也最好将超全局变量视为只读的。如果必须处理这些值,请维护自己的并行副本,并执行维护该副本所需的任何包装器/访问方法。

        3
  •  4
  •   ntzm    8 年前

    mario处理输入的类太棒了。

    我更喜欢用某种方式包装超球。它可以使您的代码更易于阅读,并带来更好的可维护性。

    例如,

    假设您创建了一个特定于应用程序的会话类。

    class Session
    {
        //some nice code
    }
    

    你可以这样写

    $session = new Session();
    if( $session->isLoggedIn() )
    {
       //do some stuff
    }
    

    if( $_SESSION['logged'] == true )
    {
       //do some stuff
    }
    

    这看起来有点微不足道,但对我来说却是件大事。假设将来某个时候我决定将索引的名称从'logged'更改为'loggedIn'。

    我现在必须去应用程序中的每个地方,会话变量被用来改变这个。或者,我可以离开它,找到一种方法来维护这两个变量。

    这有助于其他程序员查看您的代码,因为它变得更易于阅读,而且他们在查看代码时不必“思考”太多。他们可以转到该方法并看到只有一种方法可以让用户登录。它也对您有帮助,因为如果您想使“登录”检查更复杂,您只需到一个地方更改它,而不是尝试用IDE进行全局查找并尝试以这种方式更改它。

    同样,这是一个很小的例子,但是根据您如何使用会话,这种使用方法和类来保护访问的方法可以使您的生活更加轻松。

        4
  •  0
  •   HoLyVieR    14 年前

    我不建议通过引用传递superglobal。在您的类中,不清楚您要修改的是会话变量。另外,请记住,$\课程在你的课堂之外的任何地方都可以使用。从面向对象的角度来看,通过修改与类无关的变量,从类外部修改类内部的变量是非常错误的。拥有公共属性被认为是不好的做法,这甚至是最糟糕的。

        5
  •  0
  •   Daniklad    4 年前

    function get( $key, $default=FALSE ){
        return (isset($_GET[$key]) ? $_GET[$key]:$default);
    }
    function post( $key, $default=FALSE ){
        return (isset($_POST[$key]) ? $_POST[$key]:$default);
    }
    function session( $key, $default=FALSE ){
        return (isset($_SESSION[$key]) ? $_SESSION[$key]:$default);
    }
    

    $page = get('p', 'start');
    
    $first_name = post('first_name');
    $last_name = post('last_name');
    $age = post('age', -1);
    

    我发现,由于我对不同项目的验证需求大不相同,任何处理所有案例的类都必须非常庞大和复杂。所以我用香草PHP编写验证代码。

        6
  •  -3
  •   Aziz    14 年前

    这不是PHP的好用法。

    直接获取$\u会话变量:

    $id   = $_SESSION['id'];
    $hash = $_SESSION['hash'];
    

    等。