How do I get the output of phpinfo() as xml? - php

Is there a way to achieve this?
I found this function:
function phpinfo_array($return=true){
/* Andale! Andale! Yee-Hah! */
ob_start();
phpinfo(-1);
$pi = preg_replace(
array('#^.*<body>(.*)</body>.*$#ms', '#<h2>PHP License</h2>.*$#ms',
'#<h1>Configuration</h1>#', "#\r?\n#", "#</(h1|h2|h3|tr)>#", '# +<#',
"#[ \t]+#", '# #', '# +#', '# class=".*?"#', '%'%',
'#<tr>(?:.*?)" src="(?:.*?)=(.*?)" alt="PHP Logo" /></a>'
.'<h1>PHP Version (.*?)</h1>(?:\n+?)</td></tr>#',
'#<h1>PHP Credits</h1>#',
'#<tr>(?:.*?)" src="(?:.*?)=(.*?)"(?:.*?)Zend Engine (.*?),(?:.*?)</tr>#',
"# +#", '#<tr>#', '#</tr>#'),
array('$1', '', '', '', '</$1>' . "\n", '<', ' ', ' ', ' ', '', ' ',
'<h2>PHP Configuration</h2>'."\n".'<tr><td>PHP Version</td><td>$2</td></tr>'.
"\n".'<tr><td>PHP Egg</td><td>$1</td></tr>',
'<tr><td>PHP Credits Egg</td><td>$1</td></tr>',
'<tr><td>Zend Engine</td><td>$2</td></tr>' . "\n" .
'<tr><td>Zend Egg</td><td>$1</td></tr>', ' ', '%S%', '%E%'),
ob_get_clean());
$sections = explode('<h2>', strip_tags($pi, '<h2><th><td>'));
unset($sections[0]);
$pi = array();
foreach($sections as $section){
$n = substr($section, 0, strpos($section, '</h2>'));
preg_match_all(
'#%S%(?:<td>(.*?)</td>)?(?:<td>(.*?)</td>)?(?:<td>(.*?)</td>)?%E%#',
$section, $askapache, PREG_SET_ORDER);
foreach($askapache as $m)
$pi[$n][$m[1]]=(!isset($m[3])||#$m[2]==$m[3])?#$m[2]:array_slice($m,2);
}
return ($return === false) ? print_r($pi) : $pi;
}
This function returns an array with the data from phpinfo() which looks quite like a hammer-method ;)
But it seems, like phpinfo() provides data that are not to achieve otherwisee.
Now how can I correctly turn this complicated array into valid XML?

It looks like your function will return an array.
You can easily turn this into an xml using SimpleXMLElement, by walking through your array and adding the keys and values.
There are some nice answers here.

Related

How set font color in php after a character

I have a string selected from database, and I want to change the font color of string after a '<', then back to initial color after '>'. Example: rowselected= abcd<efgh>lmno
How can I change the color of efgh?
I tried with
<?php between ('<', '>', rowselected) echo '<span style="color:red;">' . rowselected . '</span>' ?>
obviusly not work, but i'm searching a solution like this
A solution using a regex to get the matches on the string and then replace them:
$str = 'abcd<efgh>lmno';
preg_match_all('/<[\S]*?>/m', $str, $matches, PREG_PATTERN_ORDER);
$replacements = $needles = [];
foreach ($matches[0] as $match) {
$needles[] = $match;
$replacements[] = '<span style="color:red;">' . $match . '</span>';
}
echo str_replace($needles, $replacements, $str);
Result: abcd<span style="color:red;"><efgh></span>lmno
You can simply apply str_replace for <> sign. Like this way
$rowselected = 'abcd<efgh>lmno';
$rowselected = str_replace('<', '<<span style="color:red">', $rowselected);
$rowselected = str_replace('>', '</span>>', $row);
// result
// "abcd<<span style="color:red"</span>>efgh</span>>lmno"

How can I avoid adding href to an overlapping keyword in string?

Using the following code:
$text = "أطلقت غوغل النسخة المخصصة للأجهزة الذكية العاملة بنظام أندرويد من الإصدار “25″ لمتصفحها الشهير كروم.ولم تحدث غوغل تطبيق كروم للأجهزة العاملة بأندرويد منذ شهر تشرين الثاني العام الماضي، وهو المتصفح الذي يستخدمه نسبة 2.02% من أصحاب الأجهزة الذكية حسب دراسة سابقة. ";
$tags = "غوغل, غوغل النسخة, كروم";
$tags = explode(",", $tags);
foreach($tags as $k=>$v) {
$text = preg_replace("/\b{$v}\b/u","$0",$text, 1);
}
echo $text;
Will give the following result:
I love PHP">love PHP</a>, but I am facing a problem
Note that my text is in Arabic.
The way is to do all in one pass. The idea is to build a pattern with an alternation of tags. To make this way work, you must before sort the tags because the regex engine will stop at the first alternative that succeeds (otherwise 'love' will always match even if it is followed by 'php' and 'love php' will never be matched).
To limit the replacement to the first occurence of each word you can remove tag from the array once it has been found and you test if it is always present in the array inside the replacement callback function:
$text = 'I love PHP, I love love but I am facing a problem';
$tagsCSV = 'love, love php, facing';
$tags = explode(', ', $tagsCSV);
rsort($tags);
$tags = array_map('preg_quote', $tags);
$pattern = '/\b(?:' . implode('|', $tags) . ')\b/iu';
$text = preg_replace_callback($pattern, function ($m) use (&$tags) {
$mLC = mb_strtolower($m[0], 'UTF-8');
if (false === $key = array_search($mLC, $tags))
return $m[0];
unset($tags[$key]);
return '<a href="index.php?s=news&tag=' . rawurlencode($mLC)
. '">' . $m[0] . '</a>';
}, $text);
Note: when you build an url you must encode special characters, this is the reason why I use preg_replace_callback instead of preg_replace to be able to use rawurlencode.
If you have to deal with an utf8 encoded string, you need to add the u modifier to the pattern and you need to replace strtolower with mb_strtolower)
the preg_split way
$tags = explode(', ', $tagsCSV);
rsort($tags);
$tags = array_map('preg_quote', $tags);
$pattern = '/\b(' . implode('|', $tags) . ')\b/iu';
$items = preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE);
$itemsLength = count($items);
$i = 1;
while ($i<$itemsLength && count($tags)) {
if (false !== $key = array_search(mb_strtolower($items[$i], 'UTF-8'), $tags)) {
$items[$i] = '<a href="index.php?s=news&tag=' . rawurlencode($tags[$key])
. '">' . $items[$i] . '</a>';
unset($tags[$key]);
}
$i+=2;
}
$result = implode('', $items);
Instead of calling preg_replace multiple times, call it a single time with a regexp that matches any of the tags:
$tags = explode(",", tags);
$tags_re = '/\b(' . implode('|', $tags) . ')\b/u';
$text = preg_replace($tags_re, '$0', $text, 1);
This turns the list of tags into the regexp /\b(love|love php|facing)\b/u. x|y in a regexp means to match either x or y.

Replace something inside CDATA with PHP

I want to replace chr(10) with
with PHP within
<!CDATA[[Text
test
test]]>
But I'm very poor in REGEX.
$xml = "cc\n<!CDATA[[Text\ntest\ntest]]>\naa\nbb\n";
$callback = function($m) {
return '<!CDATA[[' . preg_replace("~" . chr(10) . "~s", '
', $m[1]) . ']]>';
};
echo preg_replace_callback('~<!CDATA\[\[(.+?)\]\]>~s', $callback, $xml);
p.s. you can probably do it without preg_replace_callback, but it looks nicer than to put all logic into preg_replace...
Why use RegEx?
$final = str_replace( chr(10), '
', $cdata );

New line to paragraph function

I have this interesting function that I'm using to create new lines into paragraphs. I'm using it instead of the nl2br() function, as it outputs better formatted text.
function nl2p($string, $line_breaks = true, $xml = true) {
$string = str_replace(array('<p>', '</p>', '<br>', '<br />'), '', $string);
// It is conceivable that people might still want single line-breaks
// without breaking into a new paragraph.
if ($line_breaks == true)
return '<p>'.preg_replace(array("/([\n]{2,})/i", "/([^>])\n([^<])/i"), array("</p>\n<p>", '<br'.($xml == true ? ' /' : '').'>'), trim($string)).'</p>';
else
return '<p>'.preg_replace(
array("/([\n]{2,})/i", "/([\r\n]{3,})/i","/([^>])\n([^<])/i"),
array("</p>\n<p>", "</p>\n<p>", '<br'.($xml == true ? ' /' : '').'>'),
trim($string)).'</p>';
}
The problem is that whenever I try to create a single line break, it inadvertently removes the first character of the paragraph below it. I'm not familiar enough with regex to understand what is causing the problem.
Here is another approach that doesn't use regular expressions. Note, this function will remove any single line-breaks.
function nl2p($string)
{
$paragraphs = '';
foreach (explode("\n", $string) as $line) {
if (trim($line)) {
$paragraphs .= '<p>' . $line . '</p>';
}
}
return $paragraphs;
}
If you only need to do this once in your app and don't want to create a function, it can easily be done inline:
<?php foreach (explode("\n", $string) as $line): ?>
<?php if (trim($line)): ?>
<p><?=$line?></p>
<?php endif ?>
<?php endforeach ?>
The problem is with your match for single line breaks. It matches the last character before the line break and the first after. Then you replace the match with <br>, so you lose those characters as well. You need to keep them in the replacement.
Try this:
function nl2p($string, $line_breaks = true, $xml = true) {
$string = str_replace(array('<p>', '</p>', '<br>', '<br />'), '', $string);
// It is conceivable that people might still want single line-breaks
// without breaking into a new paragraph.
if ($line_breaks == true)
return '<p>'.preg_replace(array("/([\n]{2,})/i", "/([^>])\n([^<])/i"), array("</p>\n<p>", '$1<br'.($xml == true ? ' /' : '').'>$2'), trim($string)).'</p>';
else
return '<p>'.preg_replace(
array("/([\n]{2,})/i", "/([\r\n]{3,})/i","/([^>])\n([^<])/i"),
array("</p>\n<p>", "</p>\n<p>", '$1<br'.($xml == true ? ' /' : '').'>$2'),
trim($string)).'</p>';
}
I also wrote a very simple version:
function nl2p($text)
{
return '<p>' . str_replace(['\r\n', '\r', '\n'], '</p><p>', $text) . '</p>';
}
#Laurent's answer wasn't working for me - the else statement was doing what the $line_breaks == true statement should have been doing, and it was making multiple line breaks into <br> tags, which PHP's native nl2br() already does.
Here's what I managed to get working with the expected behavior:
function nl2p( $string, $line_breaks = true, $xml = true ) {
// Remove current tags to avoid double-wrapping.
$string = str_replace( array( '<p>', '</p>', '<br>', '<br />' ), '', $string );
// Default: Use <br> for single line breaks, <p> for multiple line breaks.
if ( $line_breaks == true ) {
$string = '<p>' . preg_replace(
array( "/([\n]{2,})/i", "/([\r\n]{3,})/i", "/([^>])\n([^<])/i" ),
array( "</p>\n<p>", "</p>\n<p>", '$1<br' . ( $xml == true ? ' /' : '' ) . '>$2' ),
trim( $string ) ) . '</p>';
// Use <p> for all line breaks if $line_breaks is set to false.
} else {
$string = '<p>' . preg_replace(
array( "/([\n]{1,})/i", "/([\r]{1,})/i" ),
"</p>\n<p>",
trim( $string ) ) . '</p>';
}
// Remove empty paragraph tags.
$string = str_replace( '<p></p>', '', $string );
// Return string.
return $string;
}
Here's an approach that comes with a reverse method to replace paragraphs back to regular line breaks and vice versa.
These are useful to use when building a form input. When saving a users input you may want to convert line breaks to paragraph tags, however when editing the text in a form, you may not want the user to see any html characters. Then we would replace the paragraphs back to line breaks.
// This function will convert newlines to HTML paragraphs
// without paying attention to HTML tags. Feed it a raw string and it will
// simply return that string sectioned into HTML paragraphs
function nl2p($str) {
$arr=explode("\n",$str);
$out='';
for($i=0;$i<count($arr);$i++) {
if(strlen(trim($arr[$i]))>0)
$out.='<p>'.trim($arr[$i]).'</p>';
}
return $out;
}
// Return paragraph tags back to line breaks
function p2nl($str)
{
$str = preg_replace("/<p[^>]*?>/", "", $str);
$str = str_replace("</p>", "\r\n", $str);
return $str;
}
Expanding upon #NaturalBornCamper's solution:
function nl2p( $text, $class = '' ) {
$string = str_replace( array( "\r\n\r\n", "\n\n" ), '</p><p>', $text);
$string = str_replace( array( "\r\n", "\n" ), '<br />', $string);
return '<p' . ( $class ? ' class="' . $class . '"' : '' ) . '>' . $string . '</p>';
}
This takes care of both double line breaks by converting them to paragraphs, and single line breaks by converting them to <br />
Just type this between your lines:
echo '<br>';
This will give you a new line.

How to do such string manipulations in PHP?

I need to convert
"01,02,03,04,05,07:01"
to:
<b>07</b><b>09</b><b>30</b><b class="color_blue_ball">11</b>
That is ,wrap those before : with <b></b> ,but those after : with <b class="color_blue_ball"></b>.If there's no :,all should be wrapped with <b></b>
Anyone knows how to do this?
No need for regex:
echo '<b>' . str_replace(array(',', ':'), array('</b><b>', '</b><b class="color_blue_ball">'), "01,02,03,04,05,07:01") . '</b>';
Edit: if the "01,02,03,04,05,07:01,04,06" is valid, then the idea the same but explode is added:
$parts = explode(':', "01,02,03,04,05,07,01,04:06");
echo '<b>' . str_replace(',', '</b><b>', $parts[0]) . (isset($parts[1]) ? str_replace(',', '</b><b class="color_blue_ball">', ',' . $parts[1]) : '') . '</b>';
A tad more verbose:
<?php
function wrapValues($array, $wrapper) {
$result = array();
foreach ($array as $elem) {
$result []= str_replace('?', $elem, $wrapper);
}
return implode('', $result);
}
$values = "01,02,03,04,05,07:01,02";
$firstWrapper = '<b>?</b>';
$secondWrapper = '<b class="color_blue_ball">?</b>';
list($first, $second) = explode(':', $values);
echo wrapValues(explode(',', $first), $firstWrapper) .
wrapValues(explode(',', $second), $secondWrapper);
I don't know if it's the best way to do it, but I would probably split the string on the :, then on ,, and then deal with each part separately and join them back together.

Categories