Reputation: 35
I would like to grab each of my virtual hosts configurations and put them in an array using preg_match_all so I can extract information from each of them, for example...
$vHostConfig = ' <VirtualHost *:80>
ServerName localhost
DocumentRoot c:/wamp/www
<Directory "c:/wamp/www/">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require local
</Directory>
</VirtualHost>
<VirtualHost *:8080>
ServerName testing.com
DocumentRoot c:/wamp/www/testing.com
<Directory "c:/wamp/www/testing.com">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require local
</Directory>
</VirtualHost>
<VirtualHost 127.0.0.1:80>
ServerName testing2.com
DocumentRoot c:/wamp/www/testing2.com
<Directory "c:/wamp/www/testing2.com">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require local
</Directory>
</VirtualHost>
# <VirtualHost *:80>
# ServerName testing3.com
# DocumentRoot c:/wamp/www/testing3.com
# <Directory "c:/wamp/www/testing3.com">
# Options +Indexes +Includes +FollowSymLinks +MultiViews
# AllowOverride All
# Require local
# </Directory>
# </VirtualHost>';
preg_match_all(<<what to put here>>, $vHostConfig, $vHostConfigMatches);
I would like to grab only the active configurations without a # at the beginning of the line meaning I should have three strings starting with <VirtualHost
and finishing with </VirtualHost>
in $vHostConfigMatches array. Is this possible?
Upvotes: 1
Views: 113
Reputation: 4474
Although the @trincot's answer works fine, it uses the .*?
(lazy) quantifier which makes the regex engine highly active: this regex101 shows it takes 950 steps in this example.
So I think that, even if it seems a bit more complicated, this simple PHP snippet would run faster:
$result = array_reduce(
explode(PHP_EOL, $str),
function($result, $line) {
if (trim($line[0]) <> '#') {
if (strpos($line, '<VirtualHost') !== false) {
$result[] = $line;
} else {
$result[count($result) - 1] .= $line;
}
}
return $result;
},
[]
);
At once, it merely:
Upvotes: 0
Reputation: 350137
You could use this regular expression:
preg_match_all('/^\h*<VirtualHost.*?>.*?\R\h*<\/VirtualHost>/sm',
$vHostConfig, $vHostConfigMatches);
Note that the array $vHostConfigMatches
will have an additional nesting level, so just take the first one with reset
:
print_r(reset($vHostConfigMatches));
Upvotes: 2
Reputation: 405
You could split it by line:
$lines = explode(PHP_EOL, $vhostConfig);
Filter out all of the commented lines:
$lines = array_filter($lines, function ($ele) { return substring($ele, 0) != "#"; });
Put it back together:
$vhostConfig = implode(PHP_EOL, $lines);
Then use a regex to pull each virtual host (you may want something more precise:
preg_match_all("@<VirtualHost [\d\.\*:]+>(.*?)</VirtualHost>@", $vhostConfig, $vhostConfigMatches);
Untested, but should give you the idea. This also has the benefit of ignoring any commented line in a valid virtualhost
Upvotes: 1