How to trace PHP files callstack used to render a page? - php

For many "on the rush" web development (CMS customisation or simple helping hand to a friend beggin "please help, I can't remove this div on my wordpress page") one common problem appears : what is the code behind the page where our problem lives.
Then my question is simple : is there any tool / method that can ease the searching of the scripts implied in a given page production on a php based webapp ?
Something that can build a call tree for a given page would be great !

xdebug provides a navigable callstack and much much more. On their documentation page there are a long list of wonderful things.

you're looking for debug_backtrace()
This is a particularly helpful function taken from the CakePHP framework:
function debug($var = false, $showHtml = false, $showFrom = true) {
if ($showFrom) {
$calledFrom = debug_backtrace();
echo '<strong>' . substr(str_replace(ROOT, '', $calledFrom[0]['file']), 1) . '</strong>';
echo ' (line <strong>' . $calledFrom[0]['line'] . '</strong>)';
}
echo "\n<pre class=\"debug\">\n";
$var = print_r($var, true);
if ($showHtml) {
$var = str_replace('<', '<', str_replace('>', '>', $var));
}
echo $var . "\n</pre>\n";
}

Related

How to show tree list using phpseclib?

I am using library phpseclib. To show directory listing, I use function :
$sftp->rawlist();
But it don't show the tree list as image of its example (http://phpseclib.sourceforge.net/sftp/examples.html)
How can I do to show it as image below ? Thanks.
phpseclib's documentation is in git:
https://github.com/phpseclib/docs
Looking at it... the documentation website uses http://bassistance.de/jquery-plugins/jquery-plugin-treeview/ to achieve the effect you're asking about. To convert a PHP array to HTML that'll work with that plugin...
function array2html($array)
{
$result = '';
foreach ($array as $key => $value) {
$result.= '<li><span class="name">' . $key . '</span>' . (is_array($value) ? array2html($value) : '<ul><li>' . $value . '</li></ul>') . '</li>';
}
return '<ul>' . $result . '</ul>';
}
So in PHP you'll want to do this (once the above function is defined):
echo str_replace('<ul>', '<ul class="printr">', array2html($arr), 1);
In HTML you'll then need to do this:
$(document).ready(function() {
$('.printr').treeview({ persist: "location", collapsed: true, unique: true });
}
Keep in mind it does look like the phpseclib docs did make at least one change to the tree view library (modified some CSS and added a new image):
https://github.com/phpseclib/docs/commit/3406a94489c153ddf8f4a1a33f2ecbbcdd5ec61e
Hope that helps!

Basic Template Engine Fix

I am attempting to make a (very) basic template engine for php. Based on my research I have found that a method that I am using is strongly disliked. I was wondering if anyone knew a great alternative to get the same result so I am not using it. And if anyone sees any other improvements that can be made please share!
the method that is not advised is the eval() method!
Here is the php file
<?php
class Engine {
private $vars = array();
public function assign($key, $value) {
$this->vars[$key] = $value;
}
public function render($file_name) {
$path = $file_name . '.html';
if (file_exists($path)) {
$content = file_get_contents($path);
foreach ($this->vars as $key => $value) {
$content = preg_replace('/\{' . $key . '\}/', $value, $content);
}
eval(' ?>' . $content . '<?php ');
} else {
exit('<h4>Engine Error</h4>');
}
}
}
?>
here is the index.php file
<?php
include_once 'engine.php';
$engine = new Engine;
$engine->assign('username', 'Zach');
$engine->assign('age', 21);
$engine->render('test');
?>
and here is just a test html file to display its basic function
My name is {username} and I am {age} years old!
outputs:
My name is Zach and I am 21 years old!
Many thanks in advance!
If you just want to output some text to the page, just use echo:
echo $content;
This is better than eval('?>' . $content . '<?php') for quite a few reasons: for one, if someone types in <?php phpinfo(); ?>, for example, as their username, it won't execute that code.
I would, however, note that you have some other problems. What if I do this?
$engine = new Engine;
$engine->assign('username', '{age}');
$engine->assign('age', 21);
$engine->render('test');
The {age} in the username value will be replaced with 21. Usually you don't want replacements to be replaced like that, particularly as it's order-dependent (if you assigned username later, it wouldn't happen).

Is it a good practice to use "die()" when dealing with custom PHP Exceptions?

I've wrote a custom exception class in PHP:
<?php
class Custom_Exception extends Exception {
public function __construct( $title, $message, $code = 0, Exception $previous = null ) {
parent::__construct( $message, $code, $previous );
echo '<html>';
echo '<head>';
echo '<title>Custom Exception: ' . $title . '</title>';
echo '</head>';
echo '<body>';
echo '<h1>Custom Exception</h1>';
echo '<hr />';
echo '<p><strong>Error: </strong>' . $title . '</p>';
echo '<p><strong>Message: </strong><em>' . $message . '</em></p>';
echo '<hr />';
echo '<p>This Exception was raised on: ' . date( 'Y-m-d' ) . ' at ' . date( 'H:i:s' ) . '.';
echo '</body>';
echo '</html>';
http_response_code( $code );
die();
}
}
Is it a good practice to end my __construct overriden method with die(), to prevent outputing any parent class "Exception" messages?
As you see it outputs an HTML response into the browser. I've never dealed with custom PHP exceptions before, so I would like to know does this bother any conventions, etc?
DCoder has a good point about sending the error to you or login it in a file so you can analyse it later, but about your question, die could be a bit drastic, it's much better to redirect the flow of the application to a page that informs, in plain language, that an error has happened and that the administrator will try to solve it. You can reword that in many ways.
But, the important part, is that the client should not be bothered or discouraged by the error. If you can explain the reason of the error and tell the user how to solve it, or not make it again and redirect to the last good step, that's the best way. If you can't, then you should try to explain and redirect to a safe but useful page, like the home page or a page with the error explanation and resources, like a search bot, the site map, the navigation tools or any other thing that may help.
I'd say, never just kill the application.
Bye

simple html dom unable to handle forward slash in find(id)

find() here is a function of the simple_html_dom library, that should return dom node elements when given an id/class.
$urlFetched->find("#".$id) always fails to find and return something when the $id is "fk-list-MP3-Players-/-IPods". I am guessing the problem is with the forward slash and simple_html_dom, because there is no problem with the other ids and urls(snipped).
What do I do? my program is almost complete and dependent on simple html dom.
Thanks
The code:
$urlAndIds = array(
array("http://www.flipkart.com/audio" , array('fk-list-Home-Audio', htmlentities("fk-list-MP3-Players-/-IPods"), 'fk-list-Accessories'),array('ALL','AllBrands')) );
foreach($urlAndIds as $uAI) {
$url = file_get_contents($uAI[0]) ;
$urlFetched = str_get_html($url) ;
if ($url == false){
echo 'page '.$uAI[0] . " not found" ."<br>" ."<br>";
} else {
foreach ($uAI[1] as $id) {
$idFound = $urlFetched->find("#".$id) ;
if(!$idFound) {
echo 'In page '.$uAI[0].' -id not found- '.$id ."<br>";
}
}
}
}
The slash is being interpreted as part of the XPath expression, so it's looking for a child element named -IPods. There is no XPath "quote" type function either. I'm not sure whether adding a backslash would work, but it may be easier for you to just use a normal attribute selector with id: [#id='fk-list-MP3-Players-/-IPods']

native php function to highlight javascript?

Is there any native PHP function as highlight_string(); but for javascript ?
Or, if not, is there any PHP function (homemade) to do it?
EDIT: I want to use PHP function to COLORIZE javascript
I have had great success with GeSHi. Easy to use and integrate in your app and it supports a lot of languages.
I understand you want a Syntax Highligher written in PHP. This one (Geshi) has worked for me in the past:
http://qbnz.com/highlighter/
Yes, the PHP function highlight_string() is a native PHP function for PHP.
No.
But there are a lot of javascript libraries that do syntax-highlight on several languages,
from bash-scripting to php and javascript.
eg, like snippet (JQuery) or jQuery.Syntax (my favorite)
Over here you can find an excellent library which enables syntax highlighting in a large amount of languages using javascripts and a css class.
There is no native php function to do this, so either you have to use existing libraries or you have to write something yourself.
Fastest way - you can use also PHP function "highlight_string" with a little trick
(capture function output and remove leading/trailing PHP tags):
$source = '... some javascript ...';
// option 1 - pure JS code
$htmlJs = highlight_string('<?php '.$source.' ?>', true);
$htmlJs = str_replace(array('<?php ', ' ?>'), array('', ''), $htmlJs);
// option 2 - when mixing up with PHP code inside of JS script
$htmlJs = highlight_string('START<?php '.$source.' ?>END', true);
$htmlJs = str_replace(array('START<span style="color: #0000BB"><?php </span>', ' ?>END'), array('', ''), $htmlJs);
// check PHP INI setting for "highlight.keyword" (#0000BB) - http://www.php.net/manual/en/misc.configuration.php#ini.syntax-highlighting
No native function, but rather than using a full stack library just to highlight some javascript you can use this single function :
function format_javascript($data, $options = false, $c_string = "#DD0000", $c_comment = "#FF8000", $c_keyword = "#007700", $c_default = "#0000BB", $c_html = "#0000BB", $flush_on_closing_brace = false)
{
if (is_array($options)) { // check for alternative usage
extract($options, EXTR_OVERWRITE); // extract the variables from the array if so
} else {
$advanced_optimizations = $options; // otherwise carry on as normal
}
#ini_set('highlight.string', $c_string); // Set each colour for each part of the syntax
#ini_set('highlight.comment', $c_comment); // Suppression has to happen as some hosts deny access to ini_set and there is no way of detecting this
#ini_set('highlight.keyword', $c_keyword);
#ini_set('highlight.default', $c_default);
#ini_set('highlight.html', $c_html);
if ($advanced_optimizations) { // if the function has been allowed to perform potential (although unlikely) code-destroying or erroneous edits
$data = preg_replace('/([$a-zA-z09]+) = \((.+)\) \? ([^]*)([ ]+)?\:([ ]+)?([^=\;]*)/', 'if ($2) {' . "\n" . ' $1 = $3; }' . "\n" . 'else {' . "\n" . ' $1 = $5; ' . "\n" . '}', $data); // expand all BASIC ternary statements into full if/elses
}
$data = str_replace(array(') { ', ' }', ";", "\r\n"), array(") {\n", "\n}", ";\n", "\n"), $data); // Newlinefy all braces and change Windows linebreaks to Linux (much nicer!)
$data = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $data); // Regex identifies all extra empty lines produced by the str_replace above. It is quicker to do it like this than deal with a more complicated regular expression above.
$data = str_replace("<?php", "<script>", highlight_string("<?php \n" . $data . "\n?>", true));
$data = explode("\n", str_replace(array("<br />"), array("\n"), $data));
# experimental tab level highlighting
$tab = 0;
$output = '';
foreach ($data as $line) {
$lineecho = $line;
if (substr_count($line, "\t") != $tab) {
$lineecho = str_replace("\t", "", trim($lineecho));
$lineecho = str_repeat("\t", $tab) . $lineecho;
}
$tab = $tab + substr_count($line, "{") - substr_count($line, "}");
if ($flush_on_closing_brace && trim($line) == "}") {
$output .= '}';
} else {
$output .= str_replace(array("{}", "[]"), array("<span style='color:" . $c_string . "!important;'>{}</span>", "<span style='color:" . $c_string . " !important;'>[]</span>"), $lineecho . "\n"); // Main JS specific thing that is not matched in the PHP parser
}
}
$output = str_replace(array('?php', '?>'), array('script type="text/javascript">', '</script>'), $output); // Add nice and friendly <script> tags around highlighted text
return '<pre id="code_highlighted">' . $output . "</pre>";
}
Usage :
echo format_javascript('console.log("Here is some highlighted JS code using a single function !");') ;
Credit :
http://css-tricks.com/highlight-code-with-php/
Demo :
http://css-tricks.com/examples/HighlightJavaScript/
Well nice info here . Here is another nice one : http://code.google.com/p/google-code-prettify/

Categories