Jump to content

.= causing errors


soycharliente
Go to solution Solved by mac_gyver,

Recommended Posts

Does anyone have any information about why initial variable creation/assignment with the concatenating assignment operator causes errors?

Fatal error: Call to a member function find() on null in /path/to/simple_html_dom.php on line ####.

The reference to find() is a reference to PHP Simple HTML DOM Parser.

 

Throws error after:

function getAlert($type,$message)
{
  $html .= "<div class=\"alert alert-{$type}\" role=\"alert\">";
  $html .= $message;
  $html .= "</div>";
  return $html;
}

Does not throw error after:

function getAlert($type,$message)
{
  $html = "<div class=\"alert alert-{$type}\" role=\"alert\">";
  $html .= $message;
  $html .= "</div>";
  return $html;
}

I've narrowed the problem down to when I initialize $html using the concatenating assignment operator as opposed to traditional variable assignment. Certainly I could return the string on a single line or move forward with traditional variable assignment. I think mostly my curiosity as to why I would be getting a null reference from a block of code that was working perfectly a few moments earlier is why I am posting this.

 

My truncated code, which I feel is probably irrelevant, in case there's more to it than I imagine:

<?php
include_once('simple_html_dom.php');
include_once('functions.php');
?>

<!DOCTYPE html>
<html lang="en">
<body>
<?php
if ( !$pause )
{
  echo getAlert('info','Trying to gather the data.');
  
  if ( !empty($array) )
  {
    foreach ( $array as $value )
    {
      $html = new simple_html_dom();
      $html->load_file("http://www.example.com?id={$value}");
      
      $header = $html->find("header",0);
      $name = trim($header->find("h1",0)->innertext);
      
      // More code
    }
  }
  else
  {
    // Empty array.
  }
}
else
{
  // Paused.
}
?>

</body>
</html>

Please excuse my code. I took a programming sabbatical and I'm trying to get back in.

Edited by charlieholder
Link to comment
Share on other sites

While it's possible you have found a bug in php, it's more likely something else is going on, such as errors being thrown in the actual data part of the code, and you are only seeing a part of the story.

 

For the first version of the getAlert() function definition, you should be getting an undefined variable error - Notice: Undefined variable: html in your_file on line xxxx.

 

if you are not seeing this error and it's not present in the 'view source' of the page either, either you don't have php's error_reporting set to E_ALL or you have something going on with error handling or output, such as a custom error handler or custom gzip/output buffer handler that's hiding what's really going on. make sure that php is reporting and displaying all errors. you should also turn off php's output_buffering setting (the default is on, in the php.ini.)

 

next, is your full actual code doing any header() redirects to that same page? often, unusual symptoms like this are due to a page getting requested twice, either by the browser or by the code itself, and you are seeing the result of the second request, which won't necessarily have any input data.  also, if your page is doing a header() redirect, does it have an exit; statement after the header() to stop program execution?

 

lastly, where are $pause and $array coming from in the posted code? you could have some code which you haven't shown us that is the actual cause of the problem.

Link to comment
Share on other sites

Hey mac_gyver, thanks for the reply.
 

For the first version of the getAlert() function definition, you should be getting an undefined variable error - Notice: Undefined variable: html in your_file on line xxxx.

Sorry if I wasn't more clear. The error is immediately after the function runs. getAlert() completes and echoes fine. I think it is originating in the for loop, but only happens when using the concatenating assignment operator inside of getAlert(). I added an echo statement at the top of the for loop to print an HTML comment and included that in the HTML output generated.
 

if you are not seeing this error and it's not present in the 'view source' of the page either, either you don't have php's error_reporting set to E_ALL or you have something going on with error handling or output, such as a custom error handler or custom gzip/output buffer handler that's hiding what's really going on. make sure that php is reporting and displaying all errors. you should also turn off php's output_buffering setting (the default is on, in the php.ini.)

I don't actually know where the php.ini file on my host is. When I do a phpinfo() dump into the browser, the error related fields are as follows for both Local Value and Master Value:
error_append_string - no value
error_log - syslog
error_prepend_string - no value
error_reporting - no value


I put error_reporting(E_ALL); in the top of my functions.php file and it now shows:

Notice: Undefined variable: html in /path/to/functions.php on line 40

Line 40 is the first time we see $html in the getAlert() function. (I will highlight it below.) Strangely the block of code for getAlert() still executes and moves on.
 

next, is your full actual code doing any header() redirects to that same page? often, unusual symptoms like this are due to a page getting requested twice, either by the browser or by the code itself, and you are seeing the result of the second request, which won't necessarily have any input data.  also, if your page is doing a header() redirect, does it have an exit; statement after the header() to stop program execution?

Nope. I know it's a reflex question and I'm pretty happy to say that because of this forum it's one of the first things I check when I'm doing redirects.
 

lastly, where are $pause and $array coming from in the posted code? you could have some code which you haven't shown us that is the actual cause of the problem.

Both $pause and $array and hardcoded variables near the top of my index.php file. I didn't think the full-blown code would be very useful so my apologies again. Let me show more.

functions.php

<?php
error_reporting(E_ALL);
session_start();
date_default_timezone_set('America/New_York');

function db()
{
  $hostname = 'localhost';
  $username = 'username';
  $password = 'hunter2';
  $database = 'database';
  
  $link = mysqli_connect($hostname, $username, $password, $database);
  if ( !$link ) {
    echo "Error: Unable to connect to MySQL." . PHP_EOL;
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
    exit;
  }
  return $link;
}

function mksf($link, $string)
{
  $s = get_magic_quotes_gpc() ? stripslashes($string) : $string;
  return mysqli_real_escape_string($link, $s);
}

/**
 * Get HTML for alert.
 * @param string $type
 * @param int $dismissable
 * @param string $message
 * @return string $html
 */
function getAlert($type,$dismissable,$message)
{
  $dismiss = ($dismissable) ? ' alert-dismissible': '';
  $html .= "<div class=\"alert alert-{$type}{$dismiss}\" role=\"alert\">"; // Line 40
  $html .= ($dismissable) ? "<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-label=\"Close\"><span aria-hidden=\"true\">×</span></button>" : '';
  $html .= $message;
  $html .= "</div>";
  return $html;
}

/**
 * Format swim, bike, run, and transition times.
 * @param string $text
 * @param string $tags
 * @param boolean $invert
 * @return string $text
 */
function formatTime($time)
{
  $pieces = explode(':',$time);
  if ( count($pieces) == 2 )
  {
    array_unshift($pieces,'00');
  }
  return sprintf('%02d:%02d:%02d',$pieces[0],$pieces[1],$pieces[2]);
}

/**
 * Strip all HTML tags and their content.
 * @param string $text
 * @param string $tags
 * @param boolean $invert
 * @return string $text
 */
function stripTagsContent($text,$tags='',$invert=FALSE)
{
  preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si',trim($tags),$tags);
  $tags = array_unique($tags[1]);
  if ( is_array($tags) AND count($tags) > 0 )
  {
    if ( $invert == FALSE )
    {
      return preg_replace('@<(?!(?:'.implode('|',$tags).')\b)(\w+)\b.*?>.*?</\1>@si','',$text);
    }
    else
    {
      return preg_replace('@<('.implode('|',$tags).')\b.*?>.*?</\1>@si','',$text);
    }
  }
  elseif ( $invert == FALSE )
  {
    return preg_replace('@<(\w+)\b.*?>.*?</\1>@si','',$text);
  }
  return $text;
}

?>

index.php



<?php
include_once('lib.php');
include_once('simple_html_dom.php');

$pause		= FALSE;
$showComments	= FALSE;

$rLink		= 'http://www.example.com/page.php';
$rid		= '1234567890';
$rshort		= 'example';
$rlong		= 'Example Title';
$bibs		= array(552, 874, 1767, 2507, 1618, 566);
$results	= array();
$swimTimes	= array();
$t1Times	= array();
$bikeTimes	= array();
$t2Times	= array();
$runTimes	= array();
$totalTimes	= array();
?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title></title>
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css"/>
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css" type="text/css"/>
  <link rel="stylesheet" href="style.css" type="text/css"/>
  <!--[if lt IE 9]>
    <script src="//oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="//oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  <![endif]-->
  <script src="//code.jquery.com/jquery-2.2.3.min.js" type="text/javascript"></script>
  <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" type="text/javascript"></script>
  <script src="jquery.numeric.min.js" type="text/javascript"></script>
  <script src="script.js" type="text/javascript"></script>
</head>
<body>

<div class="container-fluid">
<div class="row">
<div id="results" class="col-xs-12">
<?php
if ( !$pause )
{
  echo getAlert('info',1,'Trying to gather the data.').PHP_EOL;
  
  if ( !empty($bibs) )
  {
    foreach ( $bibs as $bib )
    {
      echo '<!-- For loop. -->'; // Added to see where error might be coming from.
      $html = new simple_html_dom();
      $html->load_file("{$rLink}?rid={$rid}&r={$rshort}&bib={$bib}");
      
      $header = $html->find("header",0);
      $name = trim(stripTagsContent($header->find("h1",0)->innertext));
      
      $overallRank = trim(stripTagsContent($header->find("div[id=div-rank]",0)->innertext));
      $divisionRank = trim(stripTagsContent($header->find("div[id=rank]",0)->innertext));
      
      $resultsTableWhite = $html->find("div[class=results-table-white]",0);
      $generalInfo = $resultsTableWhite->find("table[id=general-info]",0);
      $division = trim($generalInfo->find("td",4)->innertext);
      
      $atheleteDetails = $resultsTableWhite->find("table[id=athelete-details]",0);
      $swimTime = formatTime(trim($atheleteDetails->find("td",2)->innertext));
      $bikeTime = formatTime(trim($atheleteDetails->find("td",4)->innertext));
      $runTime = formatTime(trim($atheleteDetails->find("td",6)->innertext));
      $totalTime = formatTime(trim($atheleteDetails->find("td",->innertext));
      
      $atheleteTableDetails = $html->find("div[class=athlete-table-details]",0);
      $swimRank = trim(explode(":",$atheleteTableDetails->find("p",0)->innertext)[1]);
      $bikeRank = trim(explode(":",$atheleteTableDetails->find("p",1)->innertext)[1]);
      $runRank = trim(explode(":",$atheleteTableDetails->find("p",2)->innertext)[1]);
      $t1Time = formatTime(trim($atheleteTableDetails->find("table",3)->find("td",1)->innertext));
      $t2Time = formatTime(trim($atheleteTableDetails->find("table",3)->find("td",3)->innertext));
      
      $results[] = array(
        'name'		=> $name
        ,'bib'		=> $bib
        ,'division'	=> $division
        ,'swimTime'	=> $swimTime
        ,'t1Time'	=> $t1Time
        ,'bikeTime'	=> $bikeTime
        ,'t2Time'	=> $t2Time
        ,'runTime'	=> $runTime
        ,'totalTime'	=> $totalTime
        ,'overallRank'	=> $overallRank
        ,'divisionRank'	=> $divisionRank
        ,'swimRank'	=> $swimRank
        ,'bikeRank'	=> $bikeRank
        ,'runRank'	=> $runRank
      );
      
      if ( !in_array($swimTime,$swimTimes) ) { $swimTimes[] = $swimTime; }
      if ( !in_array($t1Time,$t1Times) ) { $t1Times[] = $t1Time; }
      if ( !in_array($bikeTime,$bikeTimes) ) { $bikeTimes[] = $bikeTime; }
      if ( !in_array($t2Time,$t2Times) ) { $t2Times[] = $t2Time; }
      if ( !in_array($runTime,$runTimes) ) { $runTimes[] = $runTime; }
      if ( !in_array($totalTime,$totalTimes) ) { $totalTimes[] = $totalTime; }
    }
    
    echo getAlert('success',1,'Results data gathered.').PHP_EOL;
    
    if ( !empty($results) )
    {
      sort($swimTimes);
      sort($t1Times);
      sort($bikeTimes);
      sort($t2Times);
      sort($runTimes);
      sort($totalTimes);
      
      echo "<table class=\"table table-hover table-condensed\">".PHP_EOL;
      echo getTableHeadFoot(array('Name','Division','OA Rank','Div Rank','SBR Ranks','Swim','T1','Bike','T2','Run','Total')).PHP_EOL;
      echo "<tbody>".PHP_EOL;
      foreach ( $results as $result )
      {
        switch ( $result['swimTime'] )
        {
          case $swimTimes[0]: $swimClass = ' gold'; break;
          case $swimTimes[1]: $swimClass = ' silver'; break;
          case $swimTimes[2]: $swimClass = ' bronze'; break;
          default: $swimClass = '';
        }
        switch ( $result['t1Time'] )
        {
          case $t1Times[0]: $t1Class = ' gold'; break;
          case $t1Times[1]: $t1Class = ' silver'; break;
          case $t1Times[2]: $t1Class = ' bronze'; break;
          default: $t1Class = '';
        }
        switch ( $result['bikeTime'] )
        {
          case $bikeTimes[0]: $bikeClass = ' gold'; break;
          case $bikeTimes[1]: $bikeClass = ' silver'; break;
          case $bikeTimes[2]: $bikeClass = ' bronze'; break;
          default: $bikeClass = '';
        }
        switch ( $result['t2Time'] )
        {
          case $t2Times[0]: $t2Class = ' gold'; break;
          case $t2Times[1]: $t2Class = ' silver'; break;
          case $t2Times[2]: $t2Class = ' bronze'; break;
          default: $t2Class = '';
        }
        switch ( $result['runTime'] )
        {
          case $runTimes[0]: $runClass = ' gold'; break;
          case $runTimes[1]: $runClass = ' silver'; break;
          case $runTimes[2]: $runClass = ' bronze'; break;
          default: $runClass = '';
        }
        switch ( $result['totalTime'] )
        {
          case $totalTimes[0]: $totalClass = ' gold'; break;
          case $totalTimes[1]: $totalClass = ' silver'; break;
          case $totalTimes[2]: $totalClass = ' bronze'; break;
          default: $totalClass = '';
        }
        $trophyIcon = ($result['divisionRank'] <= 5) ? " <span class=\"fa fa-trophy\"></span></td>" : '';
        
        echo "<tr>".PHP_EOL;
        echo "<td class=\"col-xs-2\">{$result['name']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1\">{$result['division']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1\">{$result['overallRank']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1\">{$result['divisionRank']}{$trophyIcon}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1\">{$result['swimRank']}->{$result['bikeRank']}->{$result['runRank']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1{$swimClass}\">{$result['swimTime']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1{$t1Class}\">{$result['t1Time']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1{$bikeClass}\">{$result['bikeTime']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1{$t2Class}\">{$result['t2Time']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1{$runClass}\">{$result['runTime']}</td>".PHP_EOL;
        echo "<td class=\"col-xs-1{$totalClass}\">{$result['totalTime']}</td>".PHP_EOL;
        echo "</tr>".PHP_EOL;
      }
      echo "</tbody>".PHP_EOL;
      echo "</table>".PHP_EOL;
    }
    else
    {
      echo getAlert('danger',0,'Array is empty.').PHP_EOL;
    }
  }
  else
  {
    echo getAlert('danger',0,'No bibs.').PHP_EOL;
  }
}
else
{
    echo getAlert('warning',0,'Data gather paused.').PHP_EOL;
}
?>

</div> <!-- /#results -->
</div> <!-- /row -->
</div> <!-- /container -->

</body>
</html>

HTML output at the errors:



<div class="row">
<div id="results" class="col-xs-12">
<br />
<b>Notice</b>:  Undefined variable: html in <b>/path/to/functions.php</b> on line <b>40</b><br />
<div class="alert alert-info alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>Trying to gather the data.</div>
<!-- For loop. --><br />
<b>Fatal error</b>:  Call to a member function find() on null in <b>/path/to/simple_html_dom.php</b> on line <b>1129</b><br />

Thanks.

Edited by charlieholder
Link to comment
Share on other sites

include_once('lib.php');

 

 

^^^ while this may not have anything to do with what's going on, is the included file functions.php or is it lib.php? if it's lib.php, what else is in lib.php?

 

what html output do you get if you comment out the first call to the getAlert() function or make the first $html line just an assignment statement? if you get the correct result, with no fatal run-time error, i would say you have found a php bug, because there's no way the contents of your function, with or without concatenation/an undefined variable error, should have an effect on the simple html dom class.

 

if php's error_reporting was listed as having no value, where/how were you 'seeing' the fatal run-time error at the start of this thread?

 

to try and rule out a php bug, use a different variable name, $result, inside your function definition.

 

about the only interaction/affect prior output could have between your function and the simple html dom class, is if the class is using output buffering internally, which i just searched the source file for, and there is none.

 

actually, i think i just found the problem. the simple html dom class is using error_get_last(), in the load_file() method, to check for errors, without checking what triggered the error. since your code is producing an error, this trips up the simplistic use of error_get_last() in the code.

 

short-answer: always write code that DOESN'T throw any errors during normal execution, the undefined variable error in this case, and use proper application error handling logic, by actually testing values returned by function/method calls, rather than to blindly use error_get_last().

Edited by mac_gyver
Link to comment
Share on other sites

  • 3 weeks later...

Thanks all. Work and family life hasn't left much time for me to revisit this. I'm finally able to circle back.

 

^^^ while this may not have anything to do with what's going on, is the included file functions.php or is it lib.php? if it's lib.php, what else is in lib.php?

 

I made a mistake when posting in that not only did I rename my files, but I also copy/pasted a bad version because I had made a copy of the file in order to pull out sensitive data to get help. The filename is lib.php and it's being referenced correctly.

 

what html output do you get if you comment out the first call to the getAlert() function or make the first $html line just an assignment statement? if you get the correct result, with no fatal run-time error, i would say you have found a php bug, because there's no way the contents of your function, with or without concatenation/an undefined variable error, should have an effect on the simple html dom class.

 

If I comment out the first getAlert() or make the $html line just an assignment statement, the result is the correct HTML and no errors/warnings.

 

if php's error_reporting was listed as having no value, where/how were you 'seeing' the fatal run-time error at the start of this thread?

 

The error was showing on my HTML page when the page loaded and tried to run the PHP code for generating output. It was just right there where the table should have been.

 

to try and rule out a php bug, use a different variable name, $result, inside your function definition.

 

Tested and everything functions the same in terms of errors when doing just a variable assignment and using the concatenating assignment operator.

 

actually, i think i just found the problem. the simple html dom class is using error_get_last(), in the load_file() method, to check for errors, without checking what triggered the error. since your code is producing an error, this trips up the simplistic use of error_get_last() in the code.

 

short-answer: always write code that DOESN'T throw any errors during normal execution, the undefined variable error in this case, and use proper application error handling logic, by actually testing values returned by function/method calls, rather than to blindly use error_get_last().

 

So basically whoever authored the library didn't do a good job with the error reporting/checking? I feel like I've used the concatenating assignment operator before without the PHP Simple HTML DOM Parser, but I don't have an example to share. Seems like this is not a bug, I should define my variable before using it, and move on?

 

Thanks!

Edited by charlieholder
Link to comment
Share on other sites

  • Solution
So basically whoever authored the library didn't do a good job with the error reporting/checking? I feel like I've used the concatenating assignment operator before without the PHP Simple HTML DOM Parser, but I don't have an example to share. Seems like this is not a bug, I should define my variable before using it, and move on?

 

 

that will fix the immediate issue of the simple html dom class not running, when it's not where the error is at. any php error, no matter how benign, prior to using the load() method, will cause this problem.

 

you should be defining/assigning the first line to the variable before using a concatenate operator on it anyway. every error in your code, even if the reporting/display/logging is turned off, is still being detected and handled by php. the reporting/display/logging is just the last step in the php error handling.

Link to comment
Share on other sites

TBH, and maybe it's me, since I don't do a lot of programming (it's a hobby not a career), small issues like trying to use/reference a variable I haven't defined yet tend to pop up more than I would like.

 

Thanks for the help tracking down why the errors were showing up.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.