1

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

基本上我的代码如下。

<?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';
?>

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

警告:include(marketing\cleanurl.php):无法打开流:第 27 行 /var/www/index.php 中没有此类文件或目录警告:include():无法打开“marketing\cleanurl.php”以包含(include_path='.:/usr/share/php:/usr/share/pear') 在 /var/www/index.php 第 27 行

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

现在,如果我更改包含以匹配目录,即

include 'core/marketing/cleanurl.php';

我收到以下错误

解析错误:语法错误,意外的 T_CLASS,需要 T_NS_SEPARATOR 或 ';' 或第 4 行 /var/www/twiggled/core/marketing/cleanurl.php 中的“{”

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

4

1 回答 1

2

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

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

引导/自动加载

/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) { }
于 2013-01-31T03:28:20.867 回答