php - 正确使用 php 命名空间

标签 php namespaces

我刚刚开始重建我的应用程序,我使用命名空间使 future 的开发更容易,因此我们可以重用类名。

基本上我的代码如下。

<?php
session_start();

error_reporting(E_ALL);
ini_set('display_errors', 1);

use core\marketing as marketing;
use core\security as security;
use core\structure as structure;
use core\data as data;

include 'marketing\cleanurl.php';
?>

一旦我运行它,我就会收到以下错误:

Warning: include(marketing\cleanurl.php): failed to open stream: No such file or directory in /var/www/index.php on line 27 Warning: include(): Failed opening 'marketing\cleanurl.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/index.php on line 27



我的目录结构与命名空间相匹配,因为这是我在网上读到的。

现在,如果我更改包含以匹配目录,即
include 'core/marketing/cleanurl.php';

我收到以下错误

Parse error: syntax error, unexpected T_CLASS, expecting T_NS_SEPARATOR or ';' or '{' in /var/www/twiggled/core/marketing/cleanurl.php on line 4



当我只使用 require_once 调用所有类时,这一切都有效,但发现系统的这种有限扩展并进行了更耗时的更改,并希望使用命名空间,因为它们在我使用的其他语言中一直很好。

最佳答案

由于 OP 要求它,这是使用自动加载的更新答案。

注意:当然,为了简化任务,不需要如此复杂的构造。然而,这只是一个例子(自动加载、需要、静态方法等)。

Bootstrap /自动加载

/var/www/somedir/Twiggled/bootstrap.php

<?php
namespace Twiggled;

require_once __DIR__ . '\Common\AutoLoader.php';

$autoloader = new \Twiggled\Common\AutoLoader(__NAMESPACE__, dirname(__DIR__));
$autoloader->register();

/var/www/somedir/Twiggled/Common/AutoLoader.php
<?php
namespace Twiggled\Common;

/**
 * PSR-0 Autoloader
 *
 * @package    Common
 */
class AutoLoader
{
    /**
     * @var string The namespace prefix for this instance.
     */
    protected $namespace = '';

    /**
     * @var string The filesystem prefix to use for this instance
     */
    protected $path = '';

    /**
     * Build the instance of the autoloader
     *
     * @param string $namespace The prefixed namespace this instance will load
     * @param string $path The filesystem path to the root of the namespace
     */
    public function __construct($namespace, $path)
    {
        $this->namespace = ltrim($namespace, '\\');
        $this->path      = rtrim($path, '/\\') . DIRECTORY_SEPARATOR;
    }

    /**
     * Try to load a class
     *
     * @param string $class The class name to load
     *
     * @return boolean If the loading was successful
     */
    public function load($class)
    {
        $class = ltrim($class, '\\');

        if (strpos($class, $this->namespace) === 0) {
            $nsparts   = explode('\\', $class);
            $class     = array_pop($nsparts);
            $nsparts[] = '';
            $path      = $this->path . implode(DIRECTORY_SEPARATOR, $nsparts);
            $path     .= str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';

            if (file_exists($path)) {
                require $path;
                return true;
            }
        }
        return false;
    }

    /**
     * Register the autoloader to PHP
     *
     * @return boolean The status of the registration
     */
    public function register()
    {
        return spl_autoload_register(array($this, 'load'));
    }

    /**
     * Unregister the autoloader to PHP
     *
     * @return boolean The status of the unregistration
     */
    public function unregister()
    {
        return spl_autoload_unregister(array($this, 'load'));
    }
}

打包文件

/var/www/somedir/Twiggled/Core/Helper/Strings.php
<?php
namespace Twiggled\Core\Helper;

class Strings
{
    // Note: Eventhough the method use a global PHP function name,
    // there is no problem with it - thanks to namespace.
    public static function str_replace($str) 
    {
        $str = preg_replace('/\s/', '_', strtolower($str));
        return preg_replace('/[^a-zA-Z_]/', '', $str);
    }
}

/var/www/somedir/Twiggled/Core/Marketing/Cleanurl.php
<?php
namespace Twiggled\Core\Marketing;

use \Twiggled\Core\Helper\Strings as HelperStrings;

class Cleanurl 
{
    const BASE_URL = 'http://example.com/';
    public $cleanPath;

    public function __construct($str) 
    {
        $this->cleanPath= HelperStrings::str_replace($str);
    }
}

加载并使用它..

/var/www/somedir/index.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('date.timezone', 'Europe/Berlin');

// Bootstrap the package / register autoloader
require_once __DIR__ . '\Twiggled\bootstrap.php';

use \Twiggled\Core\Marketing as Marketing;

try {
    $obj = new Marketing\Cleanurl('$This w-ork5s!');

    // prints 'http://example.com/this_works'.
    echo Marketing\Cleanurl::BASE_URL . $obj->cleanPath; 
} 
catch (\Exception $e) { }

关于php - 正确使用 php 命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14617377/

相关文章:

ASP.NET:尝试解析 Google Base XML,无法访问 "g:"标签

c# - 在 C# 中使用命名空间

php - 如何在php和mysql中连接2个数据库?

php - PHP中类的静态运算符的命名空间等价物?

php - 在 laravel 5.0 中创建图像缩略图

javascript - 从动态选择框构造 mySQL 查询

c# - 在 C# 中动态更改命名空间

c++ - 声明是否可以转义其封闭的 namespace ?

php - 有没有一种方法可以仅使用 PHP 获取 Google map 中给定地址的经度/纬度?

php - 在iphone中加密nsdata并在php中解密