在其他 php 页面中使用命名空间函数

Use namespace functions inside of other php page

提问人:SybrenMeister 提问时间:8/1/2023 最后编辑:ADysonSybrenMeister 更新时间:8/1/2023 访问量:48

问:

我正在开发一个 Web 应用程序,并越来越多地学习有关 php 路由、服务器管理等的知识。我擅长前端,但我是 php 开发的初学者。我正在学习更多关于使用命名空间和作曲家等的信息。

我遇到了一个非常奇怪的问题。我的文件夹结构如下所示:

root
  httpdocs
    index.php
    utils
      get-all-languages.php
      data-file-handler.php
      url-helpers.php
    builder
      content
        content.php
  vendor
  config
    config.php

我在 utils 文件夹中使用命名空间。

这是我的网址助手.php:

namespace App\Utils\Url;

function getRequestParam($param)
{
    // Retrieve the value of a specific parameter from the $_GET array
    return isset($_GET[$param]) ? $_GET[$param] : '';
}

function getCurrentUrl()
{
    // Get the current URL with the correct protocol and host
    $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    $url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    return $url;
}

function getCurrentLanguage($currentUrl, $redirect = false)
{
    $queryParams = getRequestQueryParams($currentUrl);
    $language = getRequestParam('language', '', $queryParams);
    $languages = \App\Utils\Languages\getAllLanguages();

    if (empty($language) || !in_array($language, $languages)) {
        if ($redirect) {
            $firstLanguage = $languages[0];
            $fallbackUrl = addOrUpdateQueryParam($currentUrl, 'language', $firstLanguage);
            header('Location: ' . $fallbackUrl);
            exit();
        };
    }

    return $language;
}

它使用命名空间 App\Utils\Languages 的 get-all-languages,.php 文件:

namespace App\Utils\Languages;

require_once(UTILS_DIR . 'data-file-handler.php');

function getAllLanguages()
{
    // Retrieve all languages from the 'languages.json' file
    $languagesData = \App\Utils\DataFileHandler\readDataFromFile(LANGUAGES_DIR . 'languages.json');

    // Sort the languages based on the 'order' key
    uasort($languagesData, function ($a, $b) {
        return $a['order'] <=> $b['order'];
    });

    // Get the sorted language keys
    $sortedLanguages = array_keys($languagesData);

    // Return the sorted languages
    return $sortedLanguages;
}

当我从 get-all-languages.php 中删除 \App\Utils\DataFileHandler\readDataFromFile 时,这两个页面工作正常。

我的数据文件处理程序.php如下所示:

namespace App\Utils\DataFileHandler;

function readDataFromFile($filePath)
{
    if (!file_exists($filePath)) {
        // Throw an exception if the file doesn't exist
        throw new Exception('File not found: ' . $filePath);
    }

    // Read and parse JSON data from a file
    $json = file_get_contents($filePath);
    return json_decode($json, true);
}

function saveDataToFile($filePath, $data)
{
    // Convert data to JSON format
    $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

    // Write JSON data to a file
    file_put_contents($filePath, $json);
}

尝试打开我的页面时,我在错误日志中收到以下错误:

AH01071:收到错误“PHP 消息:PHP 致命错误:未捕获错误:调用 到未定义的函数 App\Utils\DataFileHandler\readDataFromFile() 在 /var/www/vhosts/feeds.mailmeisters.nl/httpdocs/utils/get-all-languages.php:10\n堆栈 跟踪:\n#0 /var/www/vhosts/feeds.mailmeisters.nl/httpdocs/utils/url-helpers.php(23): App\Utils\Languages\getAllLanguages()\n#1 /var/www/vhosts/feeds.mailmeisters.nl/httpdocs/app/builder/content/content.php(12): App\Utils\Url\getCurrentLanguage()\n#2 /var/www/vhosts/feeds.mailmeisters.nl/httpdocs/index.php(56): require_once('...')\n#3 {main}\n 扔进去 /var/www/vhosts/feeds.mailmeisters.nl/httpdocs/utils/get-all-languages,.php 在线 10'

它找不到函数App\\Utils\\DataFileHandler\\readDataFromFile() in /var/www/vhosts/feeds.mailmeisters.nl/httpdocs/utils/get-all-languages.php:10

但我看不出我做错了什么。

我的composer.json也很好,我认为:

{
    "require": {
        "twig/twig": "^3.7"
    },
    "autoload": {
      "psr-4": {
        "App\\": "httpdocs/"
      }
    } 
}

因为完全相同的设置适用于我的 url-helpers,.php。我没有收到它找不到函数getAllLanguages();的错误消息。

有谁知道我在这里做错了什么,为什么我的 get-all-languages.php 找不到 data-file-handler.php 函数?

提前致谢!

PHP 命名空间

评论


答:

1赞 Halibut 8/1/2023 #1

你的常数可能是错的。如果它包含相对路径,则在运行时从使用它的文件的位置而不是定义它的文件的位置解析此路径。UTILS_DIR

为防止这种情况发生,您可以:

  • 使用绝对路径
  • 使用魔术常量开始你的路径,这将在运行时有效地将你的相对路径转换为绝对路径(推荐,因为如果你将代码移动到其他地方,它仍然有效)。有关详细信息,请参阅此处__DIR__

旁注:您在 composer.json 中定义的 PSR-4 自动加载将仅自动加载类,而不是函数。除非您在“httpdocs”文件夹中的其他位置有类,否则它不会执行任何操作。

评论

0赞 SybrenMeister 8/2/2023
多谢!@halibut。我的 util DIR 在我的配置中定义.php: define('HTTPDOCS_DIR', DIR .'/../httpdocs');“httpdocs”文件夹的路径 define('UTILS_DIR', HTTPDOCS_DIR .'/utils/');“utils”文件夹的路径 PSR-4 自动加载不加载函数的事实对我来说是新闻。您知道是否有其他方法可以自动加载函数吗?
0赞 Halibut 8/2/2023
Composer 可以做到这一点(请参阅此处)。但是它不会延迟加载文件,所以我不推荐它。相反,您可以为每个文件创建一个类,并将函数定义为这些类中的静态方法。然后,您可以删除所有说明。Composer 将延迟自动加载您的类和方法。您所要做的就是确保您的文件夹和文件名符合 PSR-4 标准。例如:Utils/DataFileHandler.php文件应包含命名空间 App\Utils 中的类 DataHandlerrequire