带有循环包含的脚本中的未定义变量(第一个脚本包含另一个包含第一个的)

Posted

技术标签:

【中文标题】带有循环包含的脚本中的未定义变量(第一个脚本包含另一个包含第一个的)【英文标题】:Undefined variable in script with circular includes (first script includes another which includes the first one) 【发布时间】:2021-10-24 23:00:34 【问题描述】:

我正在处理一个似乎有一个特点的 php 应用程序:它的一个文件 (helpers.php) 有几个函数包含另一个文件,而包含的文件 (db_connection.php) 包含该文件最初包含它。

helpers.php:

<?php

function lineBreak()

    return "\n<br>\n";


function saveScoreToDB($score)

    //session_start(); // Already started

    $usuario_id = $_SESSION["usuario_id"];
    $etapa = $_SESSION["etapa"];

    try
    
        $query_etapa = "SELECT id FROM etapas WHERE numero = $etapa";

        require_once "db_connection.php";

        // `$db_link` works perfectly fine here:
        $etapa_id = $db_link->query($query_etapa)->fetchColumn();

        $query_score = "INSERT INTO score
                            (
                                usuario_id,
                                etapa_id,
                                pontos
                            )
                                VALUES
                            (
                                $usuario_id,
                                $etapa_id,
                                $score
                            )";

        $db_link->query($query_score);
    
    catch (Exception $e)
    
        $_SESSION["error_message"] = $e->getMessage();
        header("Location: erro.php");
    


function completeTest($redirectTo)

    unset($_SESSION["etapa"]);

    $usuarioId = $_SESSION["usuario_id"];

    // TODO: try/catch

    try
    
        $queryEmailUsuario = "SELECT email FROM usuarios WHERE id = $usuarioId";
        $queryNomeUsuario = "SELECT nome FROM usuarios WHERE id = $usuarioId";

        require_once "db_connection.php";

        // `$db_link` does *not* work here. Why?
        $emailUsuario = $db_link->query($queryEmailUsuario)->fetchColumn();
        $nomeUsuario = $db_link->query($queryNomeUsuario)->fetchColumn();

        // Routine to send email using the variables above
    
    catch (Exception $ex)
    
        // TODO
    

db_connection.php:

<?php

require_once "db_credentials.php";
require_once "helpers.php";

// Variables used here come from `db_credentials.php`
$dsn = "mysql:host=$host;dbname=$dbname;port=3307;charset=utf8;";

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false
];

try

    $db_link = new PDO($dsn, $user, $pass, $options);

catch (PDOException $e)

    echo "Error connecting to the database.";
    echo lineBreak();
    echo $e->getMessage();
    echo lineBreak();
    echo lineBreak();

注意第一个脚本变量$db_link 是如何在两个不同的函数中使用的,这两个函数都包含定义此变量的文件。在第一个函数 (saveScoreToDB) 中,变量可用并且函数工作正常;但在第二个 (completeTest) 内它不可用,并且出现未定义变量错误。

这是为什么呢?如何让它发挥作用?

【问题讨论】:

【参考方案1】:

第一个require_once() 有效,因为那是“一次”,但它只在该单个函数调用的范围内,所以$db_link 在函数调用结束时被丢弃并且再也不会出现。您可以将其更改为 require(),但为每个函数调用创建一个新连接......从长远来看不会很好。

理想情况下,您创建连接一次,然后在需要的地方通过参数传递它,例如:

require_once('db_credentials.php');

saveScoreToDB($score, $db_link);
completeTest($redirectTo, $db_link)

但这可能有点乏味,对吧?这就是类变得有用的地方。

class MyThing 

  protected $db;

  public function __construct(\PDO $db) 
    $this->db = $db;
  

  public function saveScoreToDB($score) 
    $this->db->prepare(...);
  

  public function completeTest($redirectTo) 
    $this->db->prepare(...);
  


$thing = new Mything($db_link);
$thing->saveScoreToDB(42);
$thing->completeTest('yes');

【讨论】:

优秀的方法以及解释。谢谢。

以上是关于带有循环包含的脚本中的未定义变量(第一个脚本包含另一个包含第一个的)的主要内容,如果未能解决你的问题,请参考以下文章

PHP包含文件中的未定义变量错误[重复]

带有循环的 Postgres SQL 脚本

带有基本 jQuery 的未定义类型错误“defaultView”

如何通过 GetComponent 从另一个游戏对象中的另一个脚本访问变量?

“架构 x86_64 的未定义符号”试图包含来自另一个文件的函数

如何使用for循环将文本文件中的一行字符串作为Bash中另一个脚本的单独变量传递[重复]