PHPMailer Call to a member function isSMTP() on null - php

I'm trying to update my Wordpress plugin since the location of PHPMailer is moved in wordpress 5.5.
I'm testing in Wordpress version 5.1 right now and i'm encountering the following error
Fatal error: Call to a member function isSMTP() on null in (path) on line (line)
As shown in the code below i've tried var_dumping the class methods and it shows isSMTP but when i call it a line later it returns the error.
if (!class_exists("\\PHPMailer")) {
global $wp_version;
if ( version_compare( $wp_version, '5.5', '<' ) ) {
require_once(\ABSPATH . \WPINC . "/class-phpmailer.php");
require_once(\ABSPATH . \WPINC . "/class-smtp.php");
require_once(\ABSPATH . \WPINC . "/class-pop3.php");
$oPhpMailer = new \PHPMailer();
}else {
require_once(\ABSPATH . \WPINC . "/PHPMailer/PHPMailer.php");
require_once(\ABSPATH . \WPINC . "/PHPMailer/SMTP.php");
require_once(\ABSPATH . \WPINC . "/class-pop3.php");
$oPhpMailer = new PHPMailer();
}
}
var_dump(get_class_methods($oPhpMailer));
$oPhpMailer->isSMTP();

Looks like if (!class_exists("\\PHPMailer")) returns false (which means the class exists). You don't set $oPhpMailer in this case which means $oPhpMailer = null. That is what the error means: you cannot run null->isSMTP().
It could very well be that this code is ran twice - the first time the $oPhpMailer gets set because the class does not exists (which is why you get the get_class_methods output). The second time the class exists, so the variable is null.
Try adding an else
if (!class_exists("\\PHPMailer")) {
// ...
} else {
$oPhpMailer = new \PHPMailer();
}

Related

Memcached not working in web browser,but use php command working

I have testMemcached.php code below.
<?php
include_once "common.php";
include_once "api.php";
class TestMemcached extends API{
function impl(){
$m = $this->getMem();
$stats = $m->getStats();
var_dump($stats);
$m->add("Key","test");
echo "Value:".$m->get("Key");
}
}
$api = new TestMemcached();
$api->go();
I run testMemcached.php in the web browser. I get bool(false) Value:.
I run php -f testMemcached.php command then get the output below.
array(1) {
["localhost:11211"]=>
array(24) {
["pid"]=>
int(10218)
....(skip)
["version"]=>
string(6) "1.4.15"
}
}
Value:test
I don't know what the difference is and
how to fix memcached not working in the web browser.
My environment:CentOS 7. LNMP.
2018/05/23 Update :
I use telnet 127.0.0.1 11211 to test memcached function
I found the add and set is not working.
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set test testValue
ERROR
add test testValue
ERROR
get test
END
This is my memcached setup from phpinfo below.
I use getResultCode() code below to find some error
This is my test result output.
MemcachedFunction ResultCode ErrorDescription
stats 3 MEMCACHED_CONNECTION_FAILURE
set 3 MEMCACHED_CONNECTION_FAILURE
add 47 MEMCACHED_SERVER_TEMPORARILY_DISABLED
get 47 MEMCACHED_SERVER_TEMPORARILY_DISABLED
fetchAll 16 MEMCACHED_NOTFOUND
My Test Code is here. Output is in comments.
<?php
include_once 'vendor/autoload.php';
$m = new Memcached();
$m->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$m->addServer("localhost","11211");
$stats = $m->getStats();
echo "stats ".$m->getResultCode()."<br>"; // stats 3
var_dump($stats); // bool(false)
echo "<br>";
$m->set("Key","test");
echo "set ".$m->getResultCode()."<br>"; // set 3
$m->add("Key","test");
echo "add ".$m->getResultCode()."<br>"; // add 47
echo "Value:".$m->get("Key")."<br>"; // Value:
echo "get ".$m->getResultCode()."<br>"; // get 47
var_dump($m->fetchAll()); // bool(false)
echo "<br>";
echo "fetchAll ".$m->getResultCode()."<br>"; // fetchAll 16
var_dump($m->getAllKeys()); // bool(false)
I faced alittle similiar issue once.
In my case using ip address instead of 'localhost' worked.
$cache_server_host = '12*.45*.***.***';// Your server's ip address here.
$cache_server_port = 11211;
$cache_obj = NULL;
$is_cache_available = FALSE;
try {
if (class_exists('Memcache')) {
$cache_obj = new Memcache;
$is_cache_available = $cache_obj->connect($cache_server_host, $cache_server_port);
};
}
catch (Exception $e) {}
if (!empty($is_cache_available)) {
// Ok to use the cache;
// i.e.- $cache_obj->set($key, $val, ...);
}
Yes, this issue is related with IP vs hostname. I faced the same issue with official Memcached docker . it was not working with 'localhost' or 127.0.0.1 but when tested with DNS name or container IP it worked.
<?php
/**
* #license MIT License
* #copyright maartendekeizer
*/
$memcached = new Memcached();
$memcached->addServer('memcached', 11211);
$name = 'testkey';
$ttl = 10;
$data = sha1(time());
$memcached->set($name, $data, $ttl);
echo date('His') . ': key "' . $name . '" set to "' . $data . '" with ttl ' . $ttl . PHP_EOL;
for ($i = 0; $i < ($ttl + 5); $i ++) {
$res = $memcached->get($name);
echo date('His') . ': key "' . $name . '" data is "' . $res . '" and that is ' . ($res == $data ? 'a match' : 'not a match') . PHP_EOL;
sleep(1);
}

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();
// ...
}

How to debug php code in this case?

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);
}

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');
}
);

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