How to debug php code in this case? - php

I 'm developing an android app which connects to database using PHP API. It's the first time for me to encounter PHP.
What happens is that I "POST" parameters to the php code with a URL to connect to it then php makes a query to my database and store them ... the issue is that all I see is what happens in logcat, I have no idea what is goin on with the PHP so if there is something wrong in there what can I do to debug it ?
Note : I 'm already familiar with echos and var dump I 'm looking for fully debugging tool that will allow me to debug the script without actually running it directly and by that I mean accessing it from my android project.

In such cases i log / append all actions on php side into a file - with a simple
file_put_contents({file}, {data}, FILE_APPEND);
.
u could also catch nearly every error in php with following methods:
set_error_handler({YOUR_ERROR_HANDLER}, E_ALL);
register_shutdown_function({YOUR_ERROR_HANDLER});
http://php.net/manual/de/function.set-error-handler.php
http://php.net/manual/de/function.register-shutdown-function.php
example code of how would i test an envoirement in php, which i could not debug direct:
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
// will be triggered on every php shutdown - will log the last error (if one occurs)
register_shutdown_function(function()
{
// get last error
$aError = error_get_last();
if(!empty($aError))
{
logAction('called from register_shutdown_function | ' . $aError['message']);
}
});
// will be triggered on every error
set_error_handler(function($iErrCode, $sErrorText, $sErrorFile = '', $sErrorLine = '')
{
logAction('called from set_error_handler | Code: ' . $iErrCode . ' Text: ' . $sErrorText . ' File: ' . $sErrorFile . ' Line: ' . $sErrorLine);
}, E_ALL);
// will be triggered on every exception
set_exception_handler(function(\Exception $e)
{
logAction('called from set_exception_handler | Code: ' . $e->getCode() . ' Text: ' . $e->getMessage() . ' File: ' . $e->getFile() . ' Line: ' . $e->getLine());
});
// main log / debug method
function logAction($sText)
{
$sDate = date('Y.m.d H:i:s');
file_put_contents('debug.log', $sDate . ': ' . $sText, FILE_APPEND);
}

Related

What is the scope of error_get_last() in PHP?

I've been using error_get_last() in combination with register_shutdown_function() to create an error report for some of my scripts. It's been working fine for the most part.
Every now and then, though, the error report will show an error from a different script.
I'm not quite sure how that can happen. Can anyone explain?
I'm wondering if error_get_last() in one script should be able to show errors from different scripts and if that's the case, under what circumstances would that happen?
My only guess is that the error is saved for a short time so that a script that finishes execution at almost the same time might catch another script's errors. Could that be it?
This is the code I use and have included in many different PHP files:
function send_error_report($extra) {
global $conn;
$base_url = ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on' ? 'https' : 'http' ) . '://' . $_SERVER['HTTP_HOST'];
$url = $base_url . $_SERVER["REQUEST_URI"];
$error = error_get_last();
if (isset($error)) {
$error_str = "Type: " . $error['type'] . " | Message: " . $error['message'] . " | File: " . $error['file'] . " | Line: " . $error['line'];
$sql = "INSERT INTO `error_report` (`script`, `error`) VALUES ('$url', '" . $error_str . " - " . $extra . "');";
$conn->query($sql);
}
}
register_shutdown_function('send_error_report', '');

get error throwing php script name inside class

I am using Bennett Stone php wrapper class for mysqli operations. class is working fine without any issues. There is a function inside it (shared below) which sends an email to administrator for any kind of mysqli errors.
Issue
There are 100's of scripts using this class, I am not able to find out which script thrown any particular error.
What i want
I want to get the full path of error originating script inside class from where query originated. for example, test.php contains query & post execution if any error comes out then i want complete path of test.php inside error handling function along with error details (shared below).
What i can do
Class modification I can do by my own
I am getting details like this:
Error at 2016-08-23 05:44:18:
Query: SELECT email FROM users WHERE
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
Error handling function
public function log_db_errors( $error, $query )
{
$message = '<p>Error at '. date('Y-m-d H:i:s').':</p>';
$message .= '<p>Query: '. htmlentities( $query ).'<br />';
$message .= 'Error: ' . $error;
$message .= '</p>';
if( defined( 'SEND_ERRORS_TO' ) )
{
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'To: Admin <'.SEND_ERRORS_TO.'>' . "\r\n";
$headers .= 'From: systems<noreply#'.$_SERVER['SERVER_NAME'].'.com>' . "\r\n";
mail( SEND_ERRORS_TO, 'Database Error', $message, $headers );
}
else
{
trigger_error( $message );
}
if( !defined( 'DISPLAY_DEBUG' ) || ( defined( 'DISPLAY_DEBUG' ) && DISPLAY_DEBUG ) )
{
echo $message;
}
}
Put these lines somewhere above all your codes:
ini_set('display_errors', 0);
ini_set('log_errors', 1);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
and you will have every error logged with a stack trace. While all this bushy "log_db_errors" stuff will be thrown away.
the problem solved.
NB. This wrapper class is just terrible. Utilizes almost every bad practice ever exists.
What you can do is catching exception and edit error message, using some magic php const in it : PHP: Magic constants
Example, in your class, around the query :
try {
// your query
} catch (Exception $e) {
// launch your log_db_errors() function, with some of const, like __CLASS__, __LINE__, etc :
$error = '[' . __FILE__ . '][' . __CLASS__ . '::' . __FUNCTION__ . '][' . __LINE__ . '] : ' . $e->getMessage();
// ...
}

Undefined Variable in Laravel Command

I have added into a Laravel command mail::send to send an email to all users who meet the criteria. Whenever I run the first part of my foreach statement but gives me an [ErrorException] Undefined Variable: member whenever it gets to the emailing. My fire function code is below.
public function fire()
{
$members = Member::where('expire', '=', Carbon::now()->today());
$this->info('We found ' . $members->count() . ' expiring today (' . Carbon::now()->today() . ')!');
foreach ($members->get() as $member) {
$member->active = "0";
$member->save();
$this->comment($member->first_name . ' has been updated.'); //This is the last line which runs
Mail::send('emails.member.membership_expired', array('name'=>$member->first_name. ' ' . $member->last_name), function($message){
$message->to($member->email, $member->first_name . ' ' . $member->last_name)->subject('Your Membership has Expired');
});
}
}
With Mail::send you use a closure (also called anonymous function). To use local variables inside the closure you have to pass them in with use. Like that:
Mail::send('emails.member.membership_expired',
array('name'=>$member->first_name. ' ' . $member->last_name),
function($message) use ($member){
$message->to($member->email, $member->first_name . ' ' . $member->last_name)->subject('Your Membership has Expired');
}
);

PHP code is displayed in user's browser

I have a php script like this :
<?php
$confirmationCode = trim($_GET['confcode']);
$_SERVER['REMOTE_ADDR'] = 'xxx.xxx.xxx.xxx';
$emailLogId = 1;
if ($_SERVER['REMOTE_ADDR']=='xxx.xxx.xxx.xxx') {
// print '<pre>' .'xxxxx' . $emailLogId . '###'; //exit ;
}
if( is_numeric($emailLogId)) {
if ($_SERVER['REMOTE_ADDR']=='xxx.xxx.xxx.xxx') {
// print '<pre>yyy' . $_GET['emaillog_id'] . 'yyyxxxxxx ' . $emailLogId; print_r ($row) ; exit ;
}
//$osDB->query('UPDATE ! SET clicktime=? WHERE id=?', array('email_logs', time(), $emailLogId));
} else {
if ($_SERVER['REMOTE_ADDR']=='xxx.xxx.xxx.xxx') {
// print '<pre>zzz' . $_GET['emaillog_id'] . 'yyyxxxxxx ' . $emailLogId; print_r ($row) ; exit ;
}
}
?>
It is running on my server. Actually some people are complaining that they are seeing the source code of this script( pasted below ) on their browser and they send me snap shot of this issue:
' .'xxxxx' . $emailLogId . '###'; //exit ;
}
if( is_numeric($emailLogId)) {
if ($_SERVER['REMOTE_ADDR']=='xxx.xxx.xxx.xxx') {
// print '<pre>yyy' . $_GET['emaillog_id'] . 'yyyxxxxxx ' . $emailLogId; print_r ($row) ; exit ;
}
//$osDB->query('UPDATE ! SET clicktime=? WHERE id=?', array('email_logs', time(), $emailLogId));
} else {
if ($_SERVER['REMOTE_ADDR']=='xxx.xxx.xxx.xxx') {
// print '<pre>zzz' . $_GET['emaillog_id'] . 'yyyxxxxxx ' . $emailLogId; print_r ($row) ; exit ;
}
}
?>
Actually I am really confused because I am not able to reproduce this problem, but 3-4 people are complaining about same the thing.
Do you have any idea what is the issue?
Yes, similar thing happened with me too.
2 things:
. Apache configuration.
Make sure php engine is ON. If you cannot access your apache configuration file then, add this in your .htaccess:
php_flag engine on
. CDN.
If you are using any Cloud Distribution Network, it is time for you to ask them to purge your existing cache and re-load the new one.
Browser will display PHP source code ONLY AND ONLY if apache configuration is going wrong.
Hope that helps.
EDIT:
After reading Sabin's comment, I gave a second look at the code.
Problem is, he has ASSIGNED the value to $_SERVER['REMOTE_ADDR'] (line 3)
Here is how it should be:
<?php
$confirmationCode = trim($_GET['confcode']);
$ip = 'xxx.xxx.xxx.xxx';
$emailLogId = 1;
//Whatever conditions.
if ($_SERVER['REMOTE_ADDR'] == 'xxx.xxx.xxx.xxx') {
// print '<pre>' .'xxxxx' . $emailLogId . '###'; exit ;
}
if( is_numeric($emailLogId)) {
if ($_SERVER['REMOTE_ADDR'] == 'xxx.xxx.xxx.xxx') {
// print '<pre>yyy' . $_GET['emaillog_id'] . 'yyyxxxxxx ' . $emailLogId; print_r ($row) ; exit ;
}
//$osDB->query('UPDATE ! SET clicktime=? WHERE id=?', array('email_logs', time(), $emailLogId));
} else {
if ($_SERVER['REMOTE_ADDR']=='xxx.xxx.xxx.xxx') {
// print '<pre>zzz' . $_GET['emaillog_id'] . 'yyyxxxxxx ' . $emailLogId; print_r ($row) ; exit ;
}
}
?>
However, echo-ing the source code cannot be due to this. I would ask you to put FULL FILE so that we could see if you are missing a closing single quote!
It sounds like PHP is not working at all. The only reason you are not seeing the first part, is because your browsers is parsing it as if it were an HTML tag.
And Please try to print phpinfo() once,
please check for the below link, for more details
PHP code displayed in browser

New Zend added controllers stopped working showing error 500 for New Controllers, Previous Controllers Working fine

My Zend application was running fine until today, when I changed something( i mean literally nothing) which caused new controllers to stop working. I have debugged every part of the code but I can not find any traces as to why is it happening!
My Previous added controls are working, and new actions added to those also,
but new added controls dont work.
Error is this:
HTTP Error 500 (Internal Server Error): An unexpected condition was encountered while the server was attempting to fulfill the request.
same situation like this question:
Zend Error controller stopped working for 500
Any body having a solution! Please Reply,
I replaced every bit , of apache ,zend ,php library sources with new one, but with no success.
I don't think you have enough logging going on to troubleshoot this. Do you have a fatal error handler? Here is one that should help you see what's going on (Add to Boostrap class). Basically, it logs fatal errors to a log file and displays a static html page to the user.
/**
* Fatal Error Catcher which runs as a registered shutdown function
*/
public static function fatalErrorCatcher() {
$error = error_get_last();
if ($error && (
$error['type'] === E_ERROR ||
$error['type'] === E_COMPILE_ERROR ||
$error['type'] === E_CORE_ERROR ||
$error['type'] === E_PARSE
)) {
// kill the buffer content, it's broken anyway
while (ob_get_level()) {
ob_end_clean();
}
// make a summary of the error
$errorSummary = date('m/d/Y G:i:s') . ' '
. $error['message'] . ' on file ' . $error['file'] . ':' . $error['line'] . ' URL:'
. $_SERVER["SERVER_NAME"]
. ($_SERVER["SERVER_PORT"] != "80" ? ":" . $_SERVER["SERVER_PORT"] : "")
. $_SERVER["REQUEST_URI"] . "\n";
// log the error to file
file_put_contents('/var/log/fata-errors.log', $errorSummary, FILE_APPEND | LOCK_EX);
// tell the user we're sorry
header('HTTP/1.1 500 Internal Server Error');
echo file_get_contents('/var/www/html/fail-whale.html');
}
}
AND You register it in bootstrap as early in the init as possible:
register_shutdown_function(array('Bootstrap', 'fatalErrorCatcher'));

Categories