类文档

Autoload

💡 云策文档标注

概述

本文档介绍了用于 PHP Requests 库的自动加载器,支持 PSR-4 标准的 Requests 2.0.0 类,并向后兼容 PSR-0 的 Requests 1.x 类。自动加载器处理大小写敏感性问题,提供注册和加载方法。

关键要点

  • 自动加载器支持 PSR-4 的 Requests 2.0.0 类(大小写敏感)和 PSR-0 的 Requests 1.x 类(大小写不敏感)。
  • 提供 Autoload::register() 方法注册自动加载器,确保优先于 Requests 1.x 加载器。
  • 提供 Autoload::load() 方法加载类文件,处理 PSR-0 到 PSR-4 的别名映射和弃用通知。
  • 通过 deprecated_classes 数组管理旧 PSR-0 类名到新 PSR-4 类名的映射。
  • 支持通过 REQUESTS_SILENCE_PSR0_DEPRECATIONS 常量静默弃用警告。

代码示例

final class Autoload {
    private static $deprecated_classes = [
        'requests_auth' => 'WpOrgRequestsAuth',
        // 更多映射...
    ];

    public static function register() {
        if (defined('REQUESTS_AUTOLOAD_REGISTERED') === false) {
            spl_autoload_register([self::class, 'load'], true);
            define('REQUESTS_AUTOLOAD_REGISTERED', true);
        }
    }

    public static function load($class_name) {
        // 检查类名前缀
        $psr_4_prefix_pos = strpos($class_name, 'WpOrgRequests');
        if (stripos($class_name, 'Requests') !== 0 && $psr_4_prefix_pos !== 0) {
            return false;
        }

        $class_lower = strtolower($class_name);
        if ($class_lower === 'requests') {
            $file = dirname(__DIR__) . '/library/Requests.php';
        } elseif ($psr_4_prefix_pos === 0) {
            $file = __DIR__ . '/' . strtr(substr($class_name, 15), '', '/') . '.php';
        }

        if (isset($file) && file_exists($file)) {
            include $file;
            return true;
        }

        if (isset(self::$deprecated_classes[$class_lower])) {
            if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) {
                trigger_error('弃用警告...', E_USER_DEPRECATED);
                if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS')) {
                    define('REQUESTS_SILENCE_PSR0_DEPRECATIONS', true);
                }
            }
            return class_alias(self::$deprecated_classes[$class_lower], $class_name, true);
        }

        return false;
    }
}

注意事项

  • 自动加载器在队列中前置注册,以确保 Requests 2.0 加载器优先。
  • 使用 REQUESTS_AUTOLOAD_REGISTERED 常量防止重复注册。
  • 弃用 PSR-0 类名时,会触发 E_USER_DEPRECATED 警告,除非设置 REQUESTS_SILENCE_PSR0_DEPRECATIONS 为 true。
  • 类名映射不翻译,如 WpOrgRequestsAuth 保持原样。

📄 原文内容

Autoloader for Requests for PHP.

Description

This autoloader supports the PSR-4 based Requests 2.0.0 classes in a case-sensitive manner as the most common server OS-es are case-sensitive and the file names are in mixed case.

For the PSR-0 Requests 1.x BC-layer, requested classes will be treated case-insensitively.

Methods

Name Description
Autoload::load Autoloader.
Autoload::register Register the autoloader.

Source

final class Autoload {

	/**
	 * List of the old PSR-0 class names in lowercase as keys with their PSR-4 case-sensitive name as a value.
	 *
	 * @var array
	 */
	private static $deprecated_classes = [
		// Interfaces.
		'requests_auth'                              => 'WpOrgRequestsAuth',
		'requests_hooker'                            => 'WpOrgRequestsHookManager',
		'requests_proxy'                             => 'WpOrgRequestsProxy',
		'requests_transport'                         => 'WpOrgRequestsTransport',

		// Classes.
		'requests_cookie'                            => 'WpOrgRequestsCookie',
		'requests_exception'                         => 'WpOrgRequestsException',
		'requests_hooks'                             => 'WpOrgRequestsHooks',
		'requests_idnaencoder'                       => 'WpOrgRequestsIdnaEncoder',
		'requests_ipv6'                              => 'WpOrgRequestsIpv6',
		'requests_iri'                               => 'WpOrgRequestsIri',
		'requests_response'                          => 'WpOrgRequestsResponse',
		'requests_session'                           => 'WpOrgRequestsSession',
		'requests_ssl'                               => 'WpOrgRequestsSsl',
		'requests_auth_basic'                        => 'WpOrgRequestsAuthBasic',
		'requests_cookie_jar'                        => 'WpOrgRequestsCookieJar',
		'requests_proxy_http'                        => 'WpOrgRequestsProxyHttp',
		'requests_response_headers'                  => 'WpOrgRequestsResponseHeaders',
		'requests_transport_curl'                    => 'WpOrgRequestsTransportCurl',
		'requests_transport_fsockopen'               => 'WpOrgRequestsTransportFsockopen',
		'requests_utility_caseinsensitivedictionary' => 'WpOrgRequestsUtilityCaseInsensitiveDictionary',
		'requests_utility_filterediterator'          => 'WpOrgRequestsUtilityFilteredIterator',
		'requests_exception_http'                    => 'WpOrgRequestsExceptionHttp',
		'requests_exception_transport'               => 'WpOrgRequestsExceptionTransport',
		'requests_exception_transport_curl'          => 'WpOrgRequestsExceptionTransportCurl',
		'requests_exception_http_304'                => 'WpOrgRequestsExceptionHttpStatus304',
		'requests_exception_http_305'                => 'WpOrgRequestsExceptionHttpStatus305',
		'requests_exception_http_306'                => 'WpOrgRequestsExceptionHttpStatus306',
		'requests_exception_http_400'                => 'WpOrgRequestsExceptionHttpStatus400',
		'requests_exception_http_401'                => 'WpOrgRequestsExceptionHttpStatus401',
		'requests_exception_http_402'                => 'WpOrgRequestsExceptionHttpStatus402',
		'requests_exception_http_403'                => 'WpOrgRequestsExceptionHttpStatus403',
		'requests_exception_http_404'                => 'WpOrgRequestsExceptionHttpStatus404',
		'requests_exception_http_405'                => 'WpOrgRequestsExceptionHttpStatus405',
		'requests_exception_http_406'                => 'WpOrgRequestsExceptionHttpStatus406',
		'requests_exception_http_407'                => 'WpOrgRequestsExceptionHttpStatus407',
		'requests_exception_http_408'                => 'WpOrgRequestsExceptionHttpStatus408',
		'requests_exception_http_409'                => 'WpOrgRequestsExceptionHttpStatus409',
		'requests_exception_http_410'                => 'WpOrgRequestsExceptionHttpStatus410',
		'requests_exception_http_411'                => 'WpOrgRequestsExceptionHttpStatus411',
		'requests_exception_http_412'                => 'WpOrgRequestsExceptionHttpStatus412',
		'requests_exception_http_413'                => 'WpOrgRequestsExceptionHttpStatus413',
		'requests_exception_http_414'                => 'WpOrgRequestsExceptionHttpStatus414',
		'requests_exception_http_415'                => 'WpOrgRequestsExceptionHttpStatus415',
		'requests_exception_http_416'                => 'WpOrgRequestsExceptionHttpStatus416',
		'requests_exception_http_417'                => 'WpOrgRequestsExceptionHttpStatus417',
		'requests_exception_http_418'                => 'WpOrgRequestsExceptionHttpStatus418',
		'requests_exception_http_428'                => 'WpOrgRequestsExceptionHttpStatus428',
		'requests_exception_http_429'                => 'WpOrgRequestsExceptionHttpStatus429',
		'requests_exception_http_431'                => 'WpOrgRequestsExceptionHttpStatus431',
		'requests_exception_http_500'                => 'WpOrgRequestsExceptionHttpStatus500',
		'requests_exception_http_501'                => 'WpOrgRequestsExceptionHttpStatus501',
		'requests_exception_http_502'                => 'WpOrgRequestsExceptionHttpStatus502',
		'requests_exception_http_503'                => 'WpOrgRequestsExceptionHttpStatus503',
		'requests_exception_http_504'                => 'WpOrgRequestsExceptionHttpStatus504',
		'requests_exception_http_505'                => 'WpOrgRequestsExceptionHttpStatus505',
		'requests_exception_http_511'                => 'WpOrgRequestsExceptionHttpStatus511',
		'requests_exception_http_unknown'            => 'WpOrgRequestsExceptionHttpStatusUnknown',
	];

	/**
	 * Register the autoloader.
	 *
	 * Note: the autoloader is *prepended* in the autoload queue.
	 * This is done to ensure that the Requests 2.0 autoloader takes precedence
	 * over a potentially (dependency-registered) Requests 1.x autoloader.
	 *
	 * @internal This method contains a safeguard against the autoloader being
	 * registered multiple times. This safeguard uses a global constant to
	 * (hopefully/in most cases) still function correctly, even if the
	 * class would be renamed.
	 *
	 * @return void
	 */
	public static function register() {
		if (defined('REQUESTS_AUTOLOAD_REGISTERED') === false) {
			spl_autoload_register([self::class, 'load'], true);
			define('REQUESTS_AUTOLOAD_REGISTERED', true);
		}
	}

	/**
	 * Autoloader.
	 *
	 * @param string $class_name Name of the class name to load.
	 *
	 * @return bool Whether a class was loaded or not.
	 */
	public static function load($class_name) {
		// Check that the class starts with "Requests" (PSR-0) or "WpOrgRequests" (PSR-4).
		$psr_4_prefix_pos = strpos($class_name, 'WpOrg\Requests\');

		if (stripos($class_name, 'Requests') !== 0 && $psr_4_prefix_pos !== 0) {
			return false;
		}

		$class_lower = strtolower($class_name);

		if ($class_lower === 'requests') {
			// Reference to the original PSR-0 Requests class.
			$file = dirname(__DIR__) . '/library/Requests.php';
		} elseif ($psr_4_prefix_pos === 0) {
			// PSR-4 classname.
			$file = __DIR__ . '/' . strtr(substr($class_name, 15), '\', '/') . '.php';
		}

		if (isset($file) && file_exists($file)) {
			include $file;
			return true;
		}

		/*
		 * Okay, so the class starts with "Requests", but we couldn't find the file.
		 * If this is one of the deprecated/renamed PSR-0 classes being requested,
		 * let's alias it to the new name and throw a deprecation notice.
		 */
		if (isset(self::$deprecated_classes[$class_lower])) {
			/*
			 * Integrators who cannot yet upgrade to the PSR-4 class names can silence deprecations
			 * by defining a `REQUESTS_SILENCE_PSR0_DEPRECATIONS` constant and setting it to `true`.
			 * The constant needs to be defined before the first deprecated class is requested
			 * via this autoloader.
			 */
			if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) {
				// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
				trigger_error(
					'The PSR-0 `Requests_...` class names in the Requests library are deprecated.'
					. ' Switch to the PSR-4 `WpOrgRequests...` class names at your earliest convenience.',
					E_USER_DEPRECATED
				);

				// Prevent the deprecation notice from being thrown twice.
				if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS')) {
					define('REQUESTS_SILENCE_PSR0_DEPRECATIONS', true);
				}
			}

			// Create an alias and let the autoloader recursively kick in to load the PSR-4 class.
			return class_alias(self::$deprecated_classes[$class_lower], $class_name, true);
		}

		return false;
	}
}