使用PHP preg_match_all提取XAMPP httpd-vhosts.conf未注释虚拟主机
PHP提取httpd-vhosts.conf有效虚拟主机实现
需求
使用PHP的preg_match_all函数从XAMPP的httpd-vhosts.conf配置中提取有效虚拟主机,排除所有带#/##前缀的注释条目,最终输出结构化数组,包含每个有效虚拟主机的ServerName和DocumentRoot字段。
正确实现代码
<?php // 待匹配的配置内容 $str = '# Virtual Hosts # # Required modules: mod_log_config # If you want to maintain multiple domains/hostnames on your # machine you can setup VirtualHost containers for them. Most configurations # use only name-based virtual hosts so the server doesn\'t need to worry about # IP addresses. This is indicated by the asterisks in the directives below. # # Please see the documentation at # <URL:http://httpd.apache.org/docs/2.4/vhosts/> # for further details before you try to setup virtual hosts. # # You may use the command line option \'-S\' to verify your virtual host # configuration. # # Use name-based virtual hosting. # ##NameVirtualHost *:80 # # VirtualHost example: # Almost any Apache directive may go into a VirtualHost container. # The first VirtualHost section is used for all requests that do not # match a ##ServerName or ##ServerAlias in any <VirtualHost> block. # ##<VirtualHost *:80> ##ServerAdmin webmaster@dummy-host.example.com ##DocumentRoot "D:/xampp/htdocs/dummy-host.example.com" ##ServerName dummy-host.example.com ##ServerAlias www.dummy-host.example.com ##ErrorLog "logs/dummy-host.example.com-error.log" ##CustomLog "logs/dummy-host.example.com-access.log" common ##</VirtualHost> ##<VirtualHost *:80> ##ServerAdmin webmaster@dummy-host2.example.com ##DocumentRoot "D:/xampp/htdocs/dummy-host2.example.com" ##ServerName dummy-host2.example.com ##ErrorLog "logs/dummy-host2.example.com-error.log" ##CustomLog "logs/dummy-host2.example.com-access.log" common ##</VirtualHost> ##<VirtualHost *:8080> ##ServerName CI1 ##DocumentRoot D:\xampp\htdocs\codeigniter_1\public ##</VirtualHost> <VirtualHost *:8080> ServerName CI2 DocumentRoot D:\xampp\htdocs\codeigniter_2\public </VirtualHost> <VirtualHost *:8080> ServerName CI3 DocumentRoot D:\xampp\htdocs\codeigniter_3\public </VirtualHost>'; /** * 提取有效虚拟主机列表 * @param string $confContent httpd-vhosts.conf配置内容 * @return array */ function getValidVirtualHosts(string $confContent): array { $result = []; // 第一步:匹配所有未被注释的VirtualHost块 preg_match_all('/^\s*<VirtualHost\b[^>]*>(.*?)<\/VirtualHost>/ims', $confContent, $hostBlocks); if (empty($hostBlocks[1])) return $result; foreach ($hostBlocks[1] as $blockContent) { // 第二步:提取当前块中的ServerName和DocumentRoot,跳过注释行 $hostInfo = []; // 匹配ServerName if (preg_match('/^\s*ServerName\s+(\S+)/im', $blockContent, $m)) { $hostInfo['ServerName'] = $m[1]; } // 匹配DocumentRoot,处理带引号和不带引号的情况 if (preg_match('/^\s*DocumentRoot\s+["\']?([^"\'\r\n]+)["\']?/im', $blockContent, $m)) { $hostInfo['DocumentRoot'] = $m[1]; } if (!empty($hostInfo)) $result[] = $hostInfo; } return $result; } // 调用测试 $vhosts = getValidVirtualHosts($str); print_r($vhosts); ?>
输出结果
Array ( [0] => Array ( [ServerName] => CI2 [DocumentRoot] => D:\xampp\htdocs\codeigniter_2\public ) [1] => Array ( [ServerName] => CI3 [DocumentRoot] => D:\xampp\htdocs\codeigniter_3\public ) )
正则规则说明
- 匹配未注释VirtualHost块的正则
/^\s*<VirtualHost\b[^>]*>(.*?)<\/VirtualHost>/ims:^配合m修饰符匹配每行开头,自动过滤带#前缀的注释行s修饰符让.可以匹配换行符,实现跨行匹配- 非贪婪匹配
.*?保证每个闭合标签对应单独的VirtualHost块
- 提取字段的正则增加
^\s*匹配行首空白,自动排除块内的注释行
内容的提问来源于stack exchange,提问作者Sanjeev
相关产品推荐
相关产品推荐

