【问题标题】:Scope of PHP function [duplicate]PHP函数的范围[重复]
【发布时间】:2011-11-19 03:50:52
【问题描述】:

我有一个文件可以将我的可重用函数集中到一个文件中 (functions.php)。在每个需要它的页面上都有include_once()'d。当我的自定义函数尝试访问它们自己范围之外的 MySQL 连接时,我收到错误消息。源码有点像这样:

<?php
    // functions.php
    $connect = mysql_connect("localhost", "user", "pass") or die("MySQL said: ".mysql_error());
    mysql_select_db("database", $connect) or die("MySQL said: ".mysql_error()); // no error

    /* ... */

    function getmotd($user) {           
        $query = "SELECT cid FROM `users`
        WHERE id = ".$user;
        $query = mysql_query($query, $connect); // error occurs here, $connect is not a valid MySQL link-resource
        /* ... */
    }
?>

为什么我的函数不能访问在其作用域之上声明的变量?我可以通过在函数中复制$connect 的声明within 来获得成功的连接。

任何关于我如何解决这个问题或我在这里做错了什么的见解?

【问题讨论】:

    标签: php function scope


    【解决方案1】:

    你不能访问 $connect 因为它超出了函数的范围;也就是说,PHP 只能看到函数内部的变量。正如 Kemal 建议的那样,您可以使用 global 关键字让 PHP 知道该变量在函数范围之外,但我认为更好的做法是将连接传递给函数。这将为您提供更好的封装。如果你学会了通过传入你需要的资源和数据来编写你的函数(以及后来的类)(这种做法被称为“依赖注入”),你会发现你的代码更干净、更易于维护。示例如下:

    function getmotd($db, $user) {
        $query = "SELECT cid FROM users WHERE id = " . (int)$user;
        $result = mysql_query($query, $db);
        /.../
    }
    
    $connect = mysql_connect(...);
    mysql_select_db(...);
    $motd = getmotd($connect, $user);
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      使用global 关键字。

      例子

      function getmotd($user) {  
           global $connect;
          $query = "SELECT cid FROM `users`
          WHERE id = ".$user;
          $query = mysql_query($query, $connect); // error occurs here, $connect is not a valid MySQL link-resource
          /* ... */
      }
      

      你也可以这样做

      function getmotd($user) {  
          $query = "SELECT cid FROM `users`
          WHERE id = ".$user;
          $query = mysql_query($query, $GLOBALS['connect']); // error occurs here, $connect is not a valid MySQL link-resource
          /* ... */
      }
      

      如果您想制作可重复使用的代码,那么使用 OOP 可能会更好。为数据库创建一个类,并为数据库信息添加一些属性,并使用this关键字从函数中访问它们。

      【讨论】:

      • @Tural 您绝对可以在没有global 的情况下将连接变量传递给函数,并且不使用global 被认为是更好的做法。请参阅 Timothy 的答案而不是这个答案。
      猜你喜欢
      • 2011-08-22
      • 1970-01-01
      • 2020-12-28
      • 1970-01-01
      • 2015-04-25
      • 2021-11-25
      • 2015-12-20
      • 1970-01-01
      • 2012-08-03
      相关资源
      最近更新 更多