PHP域名解析与CDN加速技术
PHP域名解析与CDN加速技术
PHP应用中使用CDN可以加速静态资源的加载。今天说说PHP中实现CDN加速和域名解析的配置。
CDN的核心思想是将静态资源部署到离用户最近的节点。PHP中可以通过动态修改资源URL来实现CDN切换。
```php
class CdnManager
{
private array $cdnUrls = [];
private string $defaultCdn;
private string $localUrl;
public function __construct(string $localUrl = '', string $defaultCdn = '')
{
$this->localUrl = rtrim($localUrl, '/');
$this->defaultCdn = $defaultCdn;
}
public function addCdn(string $region, string $url): void
{
$this->cdnUrls[$region] = rtrim($url, '/');
}
public function getUrl(string $path, string $region = null): string
{
if ($region && isset($this->cdnUrls[$region])) {
$baseUrl = $this->cdnUrls[$region];
} elseif ($this->defaultCdn) {
$baseUrl = $this->defaultCdn;
} else {
$baseUrl = $this->localUrl;
}
return $baseUrl . '/' . ltrim($path, '/');
}
public function getImageUrl(string $path, array $options = []): string
{
$url = $this->getUrl('images/' . ltrim($path, '/'));
if (!empty($options)) {
$params = http_build_query($options);
$url .= '?' . $params;
}
return $url;
}
public function getJsUrl(string $path): string
{
return $this->getUrl('js/' . ltrim($path, '/'));
}
public function getCssUrl(string $path): string
{
return $this->getUrl('css/' . ltrim($path, '/'));
}
public function getVersionedUrl(string $path, string $version): string
{
$url = $this->getUrl($path);
return $url . '?v=' . $version;
}
}
$cdn = new CdnManager('http://localhost:8080', 'https://cdn.example.com');
$cdn->addCdn('china', 'https://cdn-cn.example.com');
$cdn->addCdn('us', 'https://cdn-us.example.com');
echo "CSS: " . $cdn->getCssUrl('style.css') . "\n";
echo "JS: " . $cdn->getJsUrl('app.js') . "\n";
echo "图片: " . $cdn->getImageUrl('logo.png', ['w' => 200, 'h' => 100]) . "\n";
echo "版本化: " . $cdn->getVersionedUrl('js/app.js', '1.0.3') . "\n";
?>
```
PHP中的DNS解析和域名处理:
```php
class DnsResolver
{
public function lookup(string $domain): array
{
$records = [];
// A记录
$records['a'] = dns_get_record($domain, DNS_A);
// AAAA记录
$records['aaaa'] = dns_get_record($domain, DNS_AAAA);
// MX记录
$records['mx'] = dns_get_record($domain, DNS_MX);
// NS记录
$records['ns'] = dns_get_record($domain, DNS_NS);
// TXT记录
$records['txt'] = dns_get_record($domain, DNS_TXT);
// CNAME记录
$records['cname'] = dns_get_record($domain, DNS_CNAME);
// SOA记录
$records['soa'] = dns_get_record($domain, DNS_SOA);
return $records;
}
public function checkDomainHealth(string $domain): array
{
$results = [];
$ip = gethostbyname($domain);
$results['ip'] = $ip;
$results['resolve'] = $ip !== $domain;
$connect = @fsockopen($ip, 80, $errno, $errstr, 5);
$results['http_reachable'] = $connect !== false;
if ($connect) fclose($connect);
$pingLatency = $this->measureLatency($ip);
$results['latency_ms'] = $pingLatency;
return $results;
}
private function measureLatency(string $ip): float
{
$start = microtime(true);
$socket = @fsockopen($ip, 80, $errno, $errstr, 5);
if ($socket) {
fclose($socket);
return round((microtime(true) - $start) * 1000, 2);
}
return -1;
}
public function getServerIp(): string
{
return $_SERVER['SERVER_ADDR'] ?? gethostbyname(gethostname());
}
public function getClientIp(): string
{
$headers = ['HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'];
foreach ($headers as $header) {
if (!empty($_SERVER[$header])) {
$ips = explode(',', $_SERVER[$header]);
return trim($ips[0]);
}
}
return '0.0.0.0';
}
}
$resolver = new DnsResolver();
$records = $resolver->lookup('example.com');
echo "A记录: " . ($records['a'][0]['ip'] ?? '无') . "\n";
echo "服务器IP: " . $resolver->getServerIp() . "\n";
echo "客户端IP: " . $resolver->getClientIp() . "\n";
?>
```
CDN回源配置时,需要正确获取用户真实IP:
```php
class TrustedProxies
{
private array $trustedProxies = [];
private array $trustedHeaders = [];
public function __construct(array $proxies = [])
{
$this->trustedProxies = $proxies;
$this->trustedHeaders = [
'forwarded' => 'HTTP_FORWARDED',
'x-forwarded-for' => 'HTTP_X_FORWARDED_FOR',
'x-forwarded-host' => 'HTTP_X_FORWARDED_HOST',
'x-forwarded-proto' => 'HTTP_X_FORWARDED_PROTO',
'x-real-ip' => 'HTTP_X_REAL_IP',
];
}
public function getClientIp(): string
{
$remoteIp = $_SERVER['REMOTE_ADDR'] ?? '';
if (!empty($this->trustedProxies) && in_array($remoteIp, $this->trustedProxies)) {
$forwardedFor = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? '';
if (!empty($forwardedFor)) {
$ips = explode(',', $forwardedFor);
return trim($ips[0]);
}
}
return $remoteIp;
}
public function getScheme(): string
{
$remoteIp = $_SERVER['REMOTE_ADDR'] ?? '';
if (!empty($this->trustedProxies) && in_array($remoteIp, $this->trustedProxies)) {
$proto = $_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '';
if ($proto === 'https') return 'https';
}
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
}
public function getHost(): string
{
$remoteIp = $_SERVER['REMOTE_ADDR'] ?? '';
if (!empty($this->trustedProxies) && in_array($remoteIp, $this->trustedProxies)) {
$host = $_SERVER['HTTP_X_FORWARDED_HOST'] ?? '';
if (!empty($host)) return $host;
}
return $_SERVER['HTTP_HOST'] ?? 'localhost';
}
}
?>
```
CDN和域名解析是Web应用的基础设施。PHP可以通过动态URL生成来灵活切换CDN,通过DNS函数检查域名状态。在配置CDN时,处理好用户真实IP的获取很重要,否则日志中的IP都是CDN节点的IP。合理利用CDN可以显著提升网站的加载速度。
