Colored var_dump() and errors - php

How can I set style to var_dump() function and PHP errors style, like on the next image?
At the moment I have next view of var_dump() (with <pre>var_dump(...)</pre>, without it will be all in one line) and just plain text for errors.
I searched something for PHP colored errors, var_dump styles, but could not find anything.
I used OpenServer as localhost, and on previous version I had same styles for errors, but now just plain text. Is it real to customize?

Use this code. I've been using it for years. I can't even remember where it originally came from.
function var_dump_pretty($data, $label='', $return = false) {
$debug = debug_backtrace();
$callingFile = $debug[0]['file'];
$callingFileLine = $debug[0]['line'];
ob_start();
var_dump($data);
$c = ob_get_contents();
ob_end_clean();
$c = preg_replace("/\r\n|\r/", "\n", $c);
$c = str_replace("]=>\n", '] = ', $c);
$c = preg_replace('/= {2,}/', '= ', $c);
$c = preg_replace("/\[\"(.*?)\"\] = /i", "[$1] = ", $c);
$c = preg_replace('/ /', " ", $c);
$c = preg_replace("/\"\"(.*?)\"/i", "\"$1\"", $c);
$c = preg_replace("/(int|float)\(([0-9\.]+)\)/i", "$1() <span class=\"number\">$2</span>", $c);
// Syntax Highlighting of Strings. This seems cryptic, but it will also allow non-terminated strings to get parsed.
$c = preg_replace("/(\[[\w ]+\] = string\([0-9]+\) )\"(.*?)/sim", "$1<span class=\"string\">\"", $c);
$c = preg_replace("/(\"\n{1,})( {0,}\})/sim", "$1</span>$2", $c);
$c = preg_replace("/(\"\n{1,})( {0,}\[)/sim", "$1</span>$2", $c);
$c = preg_replace("/(string\([0-9]+\) )\"(.*?)\"\n/sim", "$1<span class=\"string\">\"$2\"</span>\n", $c);
$regex = array(
// Numberrs
'numbers' => array('/(^|] = )(array|float|int|string|resource|object\(.*\)|\&object\(.*\))\(([0-9\.]+)\)/i', '$1$2(<span class="number">$3</span>)'),
// Keywords
'null' => array('/(^|] = )(null)/i', '$1<span class="keyword">$2</span>'),
'bool' => array('/(bool)\((true|false)\)/i', '$1(<span class="keyword">$2</span>)'),
// Types
'types' => array('/(of type )\((.*)\)/i', '$1(<span class="type">$2</span>)'),
// Objects
'object' => array('/(object|\&object)\(([\w]+)\)/i', '$1(<span class="object">$2</span>)'),
// Function
'function' => array('/(^|] = )(array|string|int|float|bool|resource|object|\&object)\(/i', '$1<span class="function">$2</span>('),
);
foreach ($regex as $x) {
$c = preg_replace($x[0], $x[1], $c);
}
$style = '
/* outside div - it will float and match the screen */
.dumpr {
margin: 2px;
padding: 2px;
background-color: #fbfbfb;
float: left;
clear: both;
}
/* font size and family */
.dumpr pre {
color: #000000;
font-size: 9pt;
font-family: "Courier New",Courier,Monaco,monospace;
margin: 0px;
padding-top: 5px;
padding-bottom: 7px;
padding-left: 9px;
padding-right: 9px;
}
/* inside div */
.dumpr div {
background-color: #fcfcfc;
border: 1px solid #d9d9d9;
float: left;
clear: both;
}
/* syntax highlighting */
.dumpr span.string {color: #c40000;}
.dumpr span.number {color: #ff0000;}
.dumpr span.keyword {color: #007200;}
.dumpr span.function {color: #0000c4;}
.dumpr span.object {color: #ac00ac;}
.dumpr span.type {color: #0072c4;}
';
$style = preg_replace("/ {2,}/", "", $style);
$style = preg_replace("/\t|\r\n|\r|\n/", "", $style);
$style = preg_replace("/\/\*.*?\*\//i", '', $style);
$style = str_replace('}', '} ', $style);
$style = str_replace(' {', '{', $style);
$style = trim($style);
$c = trim($c);
$c = preg_replace("/\n<\/span>/", "</span>\n", $c);
if ($label == ''){
$line1 = '';
} else {
$line1 = "<strong>$label</strong> \n";
}
$out = "\n<!-- Dumpr Begin -->\n".
"<style type=\"text/css\">".$style."</style>\n".
"<div class=\"dumpr\">
<div><pre>$line1 $callingFile : $callingFileLine \n$c\n</pre></div></div><div style=\"clear:both;\"> </div>".
"\n<!-- Dumpr End -->\n";
if($return) {
return $out;
} else {
echo $out;
}
}

You get the colored output when you ínstall and enable Xdebug:
Xdebug replaces PHP's var_dump() function for displaying variables. Xdebug's version includes different colors for different types and places limits on the amount of array elements/object properties, maximum depth and string lengths. There are a few other functions dealing with variable display as well.
You can enable/disable this with the ini setting xdebug.overload_var_dump
By default Xdebug overloads var_dump() with its own improved version for displaying variables when the html_errors php.ini setting is set to 1. In case you do not want that, you can set this setting to 0, but check first if it's not smarter to turn off html_errors.
Check the documentation for further information.
Note that you do not want to have the Xdebug extension installed on a production server as it will significantly slow down code execution.

In xdebug 3 there is no more xdebug.overload_var_dump setting. When you upgrade to xdebug 3 and you use xdebug.mode=debug as said in xdebug upgrade guide, you will not get colored output anymore. To get the same result as it was in xdebug 2 you must set xdebug.mode to develop,debug
xdebug.mode=develop,debug
Of course if you only want colored output you can only use develop mode but then you lost step debugging. With both options you get colored output and also step debugging. You can specify as many modes as you want/need. They must be separated with ,. All available modes are explained here https://xdebug.org/docs/all_settings#mode

You can also use this extension for a colored debug: (this is very easy to install)
http://www.sitepoint.com/var_dump-introducing-symfony-vardumper/
Symfony VarDumper is a component designed to replace your var_dumps. It performs essentially the same functionality, but provides you with much, much more information in a much prettier format. It’s the var_dump you’ve always wanted.

Xdebug is what you are looking for.
Sample scripts for install on Ubuntu:
[Search for Xdebug]
$ apt-cache search xdebug
[Install Xdebug]
$ sudo apt-get install php-xdebug
[Restart Apache to make it work]
$ sudo /etc/init.d/apache2 restart

In latest version of xdebug (now is 3) you should just :
1 . open php.ini
2 . change (xdebug.mode=debug) to (xdebug.mode=develop,debug)

Related

mPDF (PHP) does not recognize html check mark

I am showing a table in HTML on my web page where a check mark is shown properly (I am using ✔ for the bold check mark).
I am using classic-asp to display the HTML. The html buildup (tableOutput) is then posted to a PHP script ($output = $_POST["output"]) that uses mPDF.php (version 6.0) to print to PDF the same HTML table and somehow the check mark wont print correctly (%u2714 in printed on my PDF). All the rest of the table is printed correctly, only the check mark has a problem.
I tried adding the Symbola.ttf and Symbola_hint.ttf fonts in the mpdf\ttfonts folder but it didnt do the trick.
HTML (classic-asp):
tableOutput = tableOutput & "<TD class='center pass_x' style='font-family:symbola;'>✔</TD>"
PHP (create_report_pdf.php):
$output = $_POST["output"]; //This is the html buildup tableOutput discussed previously
$header = Irrelevant;
$footer= Irrelevant;
$mpdf = new mPDF( 'utf-8', 'A4-L', 0, '', 5, 5, 20, 20);
$mpdf->allow_charset_conversion = true;
$mpdf->WriteHTML($style,1);
$mpdf->SetHTMLHeader( $header );
$mpdf->SetHTMLFooter( $footer );
$mpdf->WriteHTML( $output );
$mpdf->Output($temp ,'F' );
config_fonts.php (I addded symbola.ttf and Symbola_hint.ttf in the mpdf\ttfonts folder):
$this->fontdata = array (
"symbola" => array (
'R' => "Symbola.ttf",
'I' => "Symbola_hint.ttf",
),
CSS (PHP $style variable points to create_report_pdf.css):
.report-table{
border: 1px solid black;
border-collapse: collapse;
font-size: 7pt;
width: 100%;
}
th,td{
font-size: 7pt;
border: 1px solid black !important;
vertical-align : middle;
}
.center{ text-align: center; vertical-align: middle; }
INPUT{
border-color:#ffffff !important;
}
.pf{ width: 45px; }
.fix-cell{ width: 90px; }
.dr-column, .dr-input{ width: 100px; }
.comments, .comments-input{ width: 130px; }
Thank you very much for your help
There are two possible solutions:
Replacing manually the %u2714 with the respective html entity ✔ by doing the following:
$output = str_replace('%u2714', '✔', $output);
Implement more generic approach that will handle all such special chars. The approach is based on the fact that %uXXXX is a non-standard notation scheme for URL-encoding Unicode characters. So you need to convert %uXXXX notation to HTML entity notation &#xXXXX; and then this can be decoded to actual UTF-8 by html_entity_decode.
$output = preg_replace('/%u([0-9A-F]+)/', '&#x$1;', $output);
$output = html_entity_decode($output, ENT_COMPAT, 'UTF-8');

Remove comments from css file

I have to read a css file and remove its commentaries, so i've decided to use the preg_replace function from php:
$original = '
/*
foo
*/
.test, input[type="text"]{ color: blue; }
/* bar */
a:hover{
text-decoration: underline;
color: red;
background: #FFF;
}';
echo preg_replace('/\/\*.*\*\//s', '', $original);
the problem is that its losing the line .test, input[type="text"]{ color: blue; }
Change .* to .*?.
echo preg_replace('#/\*.*?\*/#s', '', $original);
This will only remove /* up to the closest */ rather than the furthest.
I would approach it as follows:
\/\*((?!\*\/).*?)\*\/
\/\* # Start-of-comment
((?!\*\/).*?) # Any character 0 or more times, lazy,
# without matching an end-of-comment
\*\/ # End-of-comment
Demo
Try this:
$buffer = preg_replace('/\*[^*]*\*+([^/][^*]*\*+)*/', '', $buffer);
It doesn't work for //Comments here, but it works for the rest of /* Comment here */, even for multiple lines.
for //Comments here, use this one:
$buffer = preg_replace('/\/\*.*?\*\//s', '', $buffer);

phpsass returns a fatal error

I am using a very simple code to test phpsass
$sass = new SassParser();
$c = file_get_contents('/_www/_projects/cdn/public_html/test/test.sass');
$css = $sass->toCss($c);
The sass file is very basic:
$blue: #3bbfce;
$margin: 16px;
table.hl {
margin: 2em 0;
td.ln {
text-align: right;
}
}
li {
font: {
family: serif;
weight: bold;
size: 1.2em;
}
}
.content-navigation {
border-color: $blue;
color:
darken($blue, 9%);
}
.border {
padding: $margin / 2;
margin: $margin / 2;
border-color: $blue;
}
And I get the following error:
Fatal error: Uncaught exception 'SassNumberException' with message ' in D:\_www\_git\phpsass\script\literals\SassNumber.php on line 201
SassNumberException: Number must be a number: Array::26 Source: padding: $margin / 2; in D:\_www\_git\phpsass\script\literals\SassNumber.php on line 201
If it can help, there's also the following notice thrown before (I tried to change the error_reporting level but having the notice disappear of course didn't solve the problem):
Notice: Array to string conversion in D:\_www\_git\phpsass\SassException.php on line 25
If I use the same sass code against their online PHP compiler at http://www.phpsass.com/try/ it compiles correctly... I don't get it
Take a look at the SassParser class. The function toCss() has a second parameter called $isFile which by default is true:
public function toCss($source, $isFile = true) {
return $this->parse($source, $isFile)->render();
}
If you notice, you're passing in the source not the filename. You can either pass in the filename like so:
$sass = new SassParser();
$c = '/_www/_projects/cdn/public_html/test/test.sass';
$css = $sass->toCss($c);
Or do what you're trying to do but with an additional parameter on toCss():
$sass = new SassParser();
$c = file_get_contents('/_www/_projects/cdn/public_html/test/test.sass');
$css = $sass->toCss($c, false);
Your sass file is not really sass at all; this would be the correct syntax, basically take out all the trailing semi-colons:
$blue: #3bbfce
$margin: 16px
table.hl {
margin: 2em 0
td.ln {
text-align: right
}
}
li {
font: {
family: serif
weight: bold
size: 1.2em
}
}
.content-navigation {
border-color: $blue
color
darken($blue, 9%)
}
.border {
padding: $margin / 2
margin: $margin / 2
border-color: $blue
}
Or, like you suggested:
$sass = new SassParser(['syntax' => SassFile::SCSS]);
In fact that was a pure syntaxic problem. I tried to remove the variables from the sass code, and realized it worked - not well (margin: 2em 0 became margin: 20) but there was no error anymore.
The sass snippets that I took from http://sass-lang.com/ were not sass but scss format. The SassParser class has a parameter called syntax, which is set to 'sass' by default and needs to be set to scss when calling $scss = new SassParser(['syntax' => 'scss']).
However I needed to parse a string, not a file, but if you pass a file with a scss extension you don't need this extra parameter.

Navigation with CSS and PHP - Image Based Hover Menu (jQuery)

I have a menu that is image based (one yellow and one blue, for example). I designed the buttons in Illustrator and then converted to PNG files. Right now, I'm using CSS for hovering affects.
So when I hover over the image, it changes. So this is good (because it works), but its far from perfect (that's why I'm here)... One of my buttons in CSS looks like this:
.home_menu, .about_menu, .video_menu, .demo_menu, .contact_menu {
float: left;
margin-bottom: 10px;
margin-top: 10px;
margin-left: 10px;
width: 100px;
height: 34px;
display: block;
}
.home_menu {
background: transparent url('../images/buttons/home_but.png');
}
.home_menu:hover {
background-image: url('../images/buttons/home_but_hov.png');
}
The HTML is like started out like so:
<div id="main_menu">
</div>
So basically I'm changing the CSS background image for each class.
Two questions. First, I'm trying to get each menu to be the blue version when on that page. So I wrote a PHP function to do this (in a class), just in case I want to avoid JavaScript. It looks like this:
// Display table and loop through links and images from array
public function print_navigation($image_dir, $ds, $page_nav, $page_nav_alt, $menu) {
$current_file = explode('/', $_SERVER['PHP_SELF']);
$current_page = $current_file[count($current_file) - 1];
$current_page;
//$i = 0;
foreach ($page_nav as $key => $value) {
$menu_output .= '<a href="';
$menu_output .= $key;
$menu_output .= '" id="';
$menu_output .= $menu[$key];
$menu_output .= '" style="background: transparent url(';
if ($current_page == $key) {
$menu_output .= $image_dir . $ds . $page_nav_alt[$key];
}
else {
$menu_output .= $image_dir . $ds . $page_nav[$key];
}
$menu_output .= ');"';
$menu_output .= '></a>';
$i++;
}
echo $menu_output;
}
It seems to work for the Home page ($home variable), but not for the others. I have variables like this (arrays and variables in another file, truncated for brevity):
$menu = array(
$home => 'home_menu',
...);
$page_nav_ylw = array(
$home => $home_but_ylw,
...);
$page_nav_blu = array(
$home => $home_but_blu,
...);
Then I have all the images in variables, referenced to in the arrays, eg, $home_but_ylw refers to the PNG for that button.
The PHP function is a bit odd, because I use the $key for two arrays, which I'm sure is bad. But I'm having a hard time getting it to work otherwise.
Second question is: is there any reason I can't add JavaScript (like jQuery) right on top of this to get me the hover effects so that I can remove it from the CSS? Ideally I'd like to display the buttons with a PHP loop that also handles current page and then do the hover affects with jQuery.
Sorry for the long post. Hope it makes sense.
Thanks in advance!
If you were planning on serving your pages dynamically then I think jQuery would be a much better option. However, if your links are going to separate pages then try something this:
function printNav($Page = "home"){
$HTML = "";
$HTML .= "";
$HTML .= "";
$HTML .= "";
$HTML .= "";
echo $HTML;
}
On each separate page:
<div id="main_menu">
<?php printNav("home"); ?>
</div>
CSS:
.ActiveNav {
background-image: url('../images/buttons/blue_bg.png');
}
.MenuItem {
float: left;
margin-bottom: 10px;
margin-top: 10px;
margin-left: 10px;
width: 100px;
height: 34px;
display: block;
}
.HomeMenuItem {
background: transparent url('../images/buttons/home_but.png');
}
.HomeMenuItem:hover {
background-image: url('../images/buttons/home_but_hov.png');
}
EDIT: If you wanted a different image for each button - I would suggest using a generic button background and hover and putting the text and icons on top of it.
Based on this answer, I was able to find a work around to my problem:
PHP menu navigation
Basically, I used the GET method to get the selected class. This worked nicely. I consolidated my CSS, and was able to get this thing working.
Here is what it turned out like, for one link:
<?php $class = $_GET['selected_tab']; ?>
<div id="main_menu">
<a href="index.php/?selected_tab=home" id="home_menu" title="Home"
class="<?php if(strcmp($class, 'home') == 0) {echo 'selected';} ?>"></a>
CSS like so:
#home_menu {
background: transparent url('../images/buttons/home_but.png');
}
#home_menu:hover, #home_menu.selected {
background-image: url('../images/buttons/home_but_hov.png');
}
Next step is to convert to jQuery.
Thanks Mike GB for your help but it wasn't quite what I was looking for.

Cut strings short PHP

How would you go about Cutting strings short so it doesnt go to the next line in a div tag For example my message string contained the following:
We prefer questions that can be answered, not just discussed. Provide details. Write clearly and simply. If your question is about this website, ask it on meta instead.
And i want to preferably display it as
We prefer questions that can be answered, not just discussed. Provide ... Read More
Im thinking cutting the string short using PHP but then you have the following problem
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ... Read More
You can see that the above string can still be expanded a bit more. Any way to do this or Not, Thanks in Advance
How you can shorten a string is already answered, but your main question:
How would you go about Cutting strings short so it doesnt go to the next line in a div tag
this will not work in most cases.
for example:
iiiiiiiiii
wwwwwwwwww
You see the problem ?
this only works if your chars have the same width like:
iiiiiiiiii
wwwwwwwwww
Using PHP, you can use the wordwrap function to perform truncation:
function truncate_to_length($text, $length, $text_if_longer = "...")
{
if (strlen($text) > $length)
{
$text = wordwrap($text, $length);
$text = substr($text, 0, strpos($text, "\n"));
return $text . $text_if_longer;
}
return $text;
}
The following mostly works; the main issue is that the "...Read more" notice can cover up part of a letter. It also uses a bunch of presentational elements and requires JS. It makes me feel unclean.
The outermost element (of class .string) is used to set the overall size. .text holds the text to display. Between .string and .text in the descendent hierarchy is an element with a large width. This puts all the text in .text on one line. JS is used to show or hide the "...Read more" notice.
<style type="text/css">
.string {
height: 1em;
width: 25%;
position: relative; /* create containing block for children */
border: 1px solid black;
overflow: hidden;
background: white; /* or whatever, as long as it's not "transparent". */
}
.string .line {
width: 5000px; /* long enough for you? */
}
.string .notice {
position: absolute;
top: 0;
right: 0;
z-index: 1;
display: none;
background: inherit; /* so that the notice will completely cover up whatever's beneath */
}
</style>
<div class="string">
<div class="line"><span class="text">We prefer questions that can be answered,
not just discussed. Provide details. Write clearly and simply. If your
question is about this website, ask it on meta instead.</span></div>
</div>
<hr />
<div class="string">
<div class="line"><span class="text">Lorem ipsum dolor sit amet.</span></div>
</div>
<script>
function isOverflowed(elt) {
return elt.offsetWidth > elt.parentNode.parentNode.clientWidth;
}
function getNotice(textElt) {
try {
return (textElt.parentNode.parentNode.getElementsByClassName('notice'))[0];
} catch (e) {
return {style: {}};
}
}
function show(elt) {
elt.style.display = 'block';
}
function hide(elt) {
elt.style.display = 'none';
}
function showReadMoreNotices() {
var text=document.getElementsByClassName('text');
for (var i=0; i<text.length; ++i) {
if (isOverflowed(text[i])) {
show(getNotice(text[i]));
} else {
hide(getNotice(text[i]));
}
}
}
var strings = document.getElementsByClassName('string');
var notice = document.createElement('div');
notice.appendChild(document.createTextNode('\u2026Read more'));
notice.className = 'notice';
for (var i=0; i<strings.length; ++i) {
strings[i].appendChild(notice.cloneNode(true));
}
showReadMoreNotices();
/* use your favorite event registration method here. Not that the traditional
* model is my favorite, it's just simple.
*/
window.onresize = showReadMoreNotices;
</script>
Check the size, if the size is greater than your maximum, take the leftmost characters.
Leftmost # = Total size - size("... read more").
Then append the read more to the left most characters.
Jacob
Here is an example taken from http://snippetdb.com/php/truncate-string:
function Truncate ($str, $length=10, $trailing='...')
{
// take off chars for the trailing
$length-=strlen($trailing);
if (strlen($str) > $length)
{
// string exceeded length, truncate and add trailing dots
return substr($str,0,$length).$trailing;
}
else
{
// string was already short enough, return the string
$res = $str;
}
return $res;
}
Oooo i came up with something that works but not works completely... Id like to share
div.string{
height:15px;
overflow:hidden;
}
It solves the problem that it will hide the whole word that wont fit in to the end of line.., because of the overflow and the height is set to one line only. However the above still dosent do the Problem shown by Rufinus:
iiiiiiiiiiiiii
wwwwwwwwwwwwww
This is a function picked from smarty templates that shortens strings without cutting them.
function str_short($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
if ($length == 0)
return '';
if (strlen($string) > $length) {
$length -= min($length, strlen($etc));
if (!$break_words && !$middle) {
$string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
}
if(!$middle) {
return substr($string, 0, $length) . $etc;
} else {
return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
}
} else {
return $string;
}
}
It all depends on the font. Of course, you can use a monospace font, but that isn't a solution. Anyway, why would you like to do this? Even if you manage to make it work on a certain font, it might be that an user doesn't have it. Then a different font will be used, and everything may break...
It would be basically impossible to do this in PHP with a non monospace font (even with a monospace font, it is difficult to tell exactly how long a string in going to be in a certain browser. The only way I can think of doing this in a browser is to put it in a and set the width of a the span to be a certain width then use overflow: hidden.
Depending on what browser you're using, this one line of CSS could do the trick:
div.string {
word-wrap: break-word;
}
If you know what true-type font the browser is using, you can use the imagettfbbox() in the GD library to calculate the width of your text. Then iterate and drop characters off of the end of the text until it fits into your div.
This may not be very efficient, I know that, but it does the job. You could fine-tune and optimize for your specific solution.
<?
$width = 280; // max. width in pixels that the text should have
$font = 'C:\Windows\Fonts\verdana.TTF';
$text = 'The quick brown fox jumps over the lazy dog';
function getWidth($text) {
list($x1, , $x2) = imagettfbbox(12, 0, $font, $text);
return $x2-$x1;
}
while (getWidth($text.'...') > $width) $text = substr($text, 0, -1);
?>
<style type='text/css'>
#my_div {
font-family: Verdana;
font-size: 12pt;
border: 1px solid black;
width: 280px;
padding: 0
}
</style>
<div id='my_div'>
<?=$text?>...
</div>

Categories