Error: Undefined Variable

I am receiving this error in my error log. What does it mean?
Server Error Log
Error Info
ErrorException: Undefined variable: highlight - pages/specs.php:267
Generated By: Unknown Account, Today at 11:56 AM
Stack Trace
#0 /home3/jes269/public_html/pages/specs.php(267): XenForo_Application::handlePhpError(8, 'Undefined varia...', '/home3/jes269/p...', 267, Array)
#1 /home3/jes269/public_html/library/XenForo/Pages/Specs.php(7): require('/home3/jes269/p...')
#2 [internal function]: XenForo_Pages_Specs::includeFile(Object(NodesAsTabs_ControllerPublic_Page), Object(XenForo_ControllerResponse_View))
#3 /home3/jes269/public_html/library/XenForo/ControllerPublic/Page.php(46): call_user_func_array(Array, Array)
#4 /home3/jes269/public_html/library/XenForo/FrontController.php(347): XenForo_ControllerPublic_Page->actionIndex()
#5 /home3/jes269/public_html/library/XenForo/FrontController.php(134): XenForo_FrontController->dispatch(Object(XenForo_RouteMatch))
#6 /home3/jes269/public_html/index.php(13): XenForo_FrontController->run()
#7 {main}
Request State
array(3) {
["url"] => string(74) "http://wearabletechforums.com/compare/specs/?vs=peak&vs=surge&vs=vivosmart"
["_GET"] => array(1) {
["vs"] => string(9) "vivosmart"
}
["_POST"] => array(0) {
}
}
 
The other thread is basically the same code generating a slightly different error, hence I've closed that thread as it's the same answer.
 
Well, I'm the developer of that. I used the includeFile callback, and $highlight is a variable I use in the PHP file called into the page node. The PHP file does not itself interact with XenForo. What does the error mean?
 
There isn't an "includeFile" callback included with XenForo. Not sure what you're referring to there.

It's not a XenForo troubleshooting issue, it's an issue with your code so I have moved this into the Development Discussions forum. To debug it we would need to see your code, without it it's not possible to advise what the problem might be.
 
Screen Shot 2014-12-31 at Wed, Dec 31, 3.39 PM.webp
/libary/XenForo/Pages/Specs.php:
Code:
<?php
class XenForo_Pages_Specs
{
     public static function includeFile(XenForo_ControllerPublic_Abstract  $controller, XenForo_ControllerResponse_Abstract &$response)
    {
        ob_start();
        require('/home3/jes269/public_html/pages/specs.php');
        $myContent = ob_get_contents();
        ob_end_clean();
      
        ob_start();
        require('/home3/jes269/public_html/pages/sidebar.php');
        $mySidebar = ob_get_contents();
        ob_end_clean();

        $params = array(
            'myContent'  => $myContent,
            'mySidebar'  => $mySidebar,
            'myTitle'  => $myTitle
        );

        $response->params = array_merge(
            $response->params,
            $params
        );
    }
}
?>

/pages/specs.php:
Code:
[removed]
 
Last edited:
This code here:
PHP:
    // Determine if row highlighting should be enabled
    if(count($validSelections)<=2 && count(array_unique($spec))!=1 && $fields[$row] != 'reviews' && $fields[$row] != 'link_site') {
        $highlight="specHighlight";
    } else {
        unset($highlight);
    }

Instead of:

PHP:
else {
        unset($highlight);
    }

Change it to:

PHP:
else {
        $highlight = '';
    }
 
Is there a reason I can't unset my own variables?
You can unset a variable (although you don't need to as the garbage collector will do it for you at some point) but you will have to re-declare it, by assigning a value to it, if you wish to use it again.
As for your other errors, you have removed your code sample above so can only guess you either have some empty arrays or other unset variables are being called.

Off to party now...
Happy New Year
 
Happy New Year.
Code:
<?php

// Build array of selections
$getSelections=array();
if($_SERVER['QUERY_STRING']!="") {
    $params = explode('&', $_SERVER['QUERY_STRING']);
    foreach ($params as $param) {
        $name_value = explode('=', $param);
        $name = $name_value[0];
        $value = $name_value[1];
        array_push($getSelections, $name_value[1]);
    }
}

// Connect to db
include_once('connect.php');
$connection = mysqli_connect($host, $user, $password, $db) or die();
mysqli_select_db($connection, $db);

// Build list of acceptable shortnames
$acceptableShortnames = array();
$acceptableNames = array();
$acceptableShortnames_SQL = mysqli_query($connection, "SELECT DISTINCT shortname, name FROM compare_wearables ORDER BY name") or die(mysqli_error($connection));
while($getShortnames = mysqli_fetch_assoc($acceptableShortnames_SQL)) {
    $acceptableShortnames[] = $getShortnames['shortname'];
    $acceptableNames[$getShortnames['shortname']] = $getShortnames['name'];
}

// Validate selections against acceptable shortnames
$validSelections = array();
foreach($getSelections as $selection) {
    if(in_array($selection, $acceptableShortnames)) {
        $validSelections[] = $selection; 
    }
}

// If no valid selections, pick some randomly
// This would be a good place to limit selections, server-side, to the quantity specified on the prior page
if(count($validSelections) < 1) {
    $showAlert_Random = 1;
    $randomSelections = array_rand($acceptableShortnames, 3);
    $validSelections = array();
    foreach($randomSelections as $randomSelection) {
        $validSelections[] = $acceptableShortnames[$randomSelection];
    }
}

// Get specs on valid selections
$validSelectionsStr = implode("','", $validSelections);
$specs_SQL = mysqli_query($connection, "SELECT * FROM compare_wearables WHERE shortname in('".$validSelectionsStr."') ORDER BY name") or die(mysqli_error($db));

// Build data array
$specs = array();
while($item = mysqli_fetch_assoc($specs_SQL)) {
    $fields = array_keys($item); // Can I make this more efficient?
    foreach($fields as $field) {
        $specs[$field][] = $item[$field];
    }
}

// Close connection
mysqli_close($connection);

?>

<div class="bigBanner bB2">

<?php
// Heading for side-by-side comparison
if(count($validSelections)>=2) {
    echo "<h1><i class=\"fa fa-bar-chart\"></i>&nbsp; Wearables Comparison Tool</h1>";
    ?><div><?php
    for($column=0; $column<count($validSelections); $column++) {
        if($column>0) {
            $myTitle .= " vs.&nbsp;";
        }
        $fullName=str_replace(" ", "&nbsp;", $specs['name'][$column]);
        $myTitle .= $fullName;
        unset($fullName);
    }
    echo $myTitle;
    $myTitle = 'Compare ' . $myTitle; // for HTML <title>
    ?></div><?php
}
// Heading for single item page
else {
    echo "<h1><i class=\"fa fa-info-circle\"></i>&nbsp; " . $specs['name'][0] . "</h1>";
    echo "<div>Features and Specifications</div>";
    $myTitle = $specs['name'][0] . ": Features and Specifications"; // for HTML <title>
}
?>

</div>

<?php

// Show alert if no selections
if($showAlert_Random == 1) {
    echo "<a href=\"/compare/\" class=\"specialButton sB3-inverse sB-xlg sB-left\">
    <strong>You did not select any wearables to compare, so here are 3 selected at random.</strong> Click here to make your own side-by-side comparison.</a>";

}
   
?>

<div class="selectOther-tinyButtons"><a href="/compare/" class="displayWhenResponsive specialButton sB1 sB-tiny"><i class="fa fa-arrow-circle-left"></i>&nbsp; Select other wearables</a></div>


<?php
// Use sticky code if comparison
if(count($validSelections)>=2) {

    echo "\t<script type=\"text/javascript\" src=\"/pages/jquery.sticky.js\"></script>
    <script>
    $(function(){
        if ($(window).width() > 700) {
            $(\".sticky\").sticky({topSpacing:0, getWidthFrom: \"#comparisonSpecs\", responsiveWidth: true});
        }
        var eventFired = 0;
        $(window).on('resize', function() {
            if (!eventFired) {
                if ($(window).width() > 700) {
                    $(\".sticky\").sticky({topSpacing:0, getWidthFrom: \"#comparisonSpecs\", responsiveWidth: true});
                }
            }
        });
    });
    </script>";

} ?>

<div id="comparison">
    <div class="sticky">
        <table class="sticky">
   
<?php

$colwidth = round(100/(count($validSelections)+1),1);

// Head row
echo "\t<tr><th class=\"specField\" width=\"" . $colwidth . "%\">&nbsp;</th>";
for($column=0; $column<count($validSelections); $column++) {
    echo "<th class=\"" . $specs['shortname'][$column] . "\" width=\"" . $colwidth . "%\"><h3>" . $specs['name'][$column] . "</h3></th>";
}
echo "</tr>\n";

// Image row
echo "\t<tr class=\"specImage\"><td class=\"specField\">&nbsp;</td>";
for($column=0; $column<count($validSelections); $column++) {
    echo "<td class=\"".$specs['shortname'][$column]." spec\"><img src=\"/images/compare-".$specs['shortname'][$column].".jpg\" alt=\"".$specs['name'][$column]."\"></td>";
}
echo "</tr>\n";

// Removal button row
if(count($validSelections)>1) {
    echo "\t<tr class=\"removeSelection\"><td class=\"specField\">&nbsp;</td>";
    for($column=0; $column<count($validSelections); $column++) {
        $newURL="/compare/specs/?";
        $subsequent=0;
        foreach($validSelections as $part) {
            if($part!=$specs['shortname'][$column]) {
                if($subsequent>=1) {
                    $newURL=$newURL."&amp;";
                }
                $newURL=$newURL."vs=".$part;
                $subsequent++;
            }
        }
        unset($subsequent);
        echo "<td class=\"".$specs['shortname'][$column]." spec specNeutral\"><a href=\"".$newURL."\" class=\"specialButton sB3-inverse sB-tiny sB-block\"><i class=\"fa fa-ban\"></i> Remove</a></td>";
        unset($removeSelectionURL);
    }
    echo "</tr>\n";
}

?>

        </table>
    </div>
    <table id="comparisonSpecs">

<?php

// Data rows
$row = 0;
$colspan = count($validSelections) + 1;
foreach($specs as $spec) {
       
    // Category rows
    $categoryBreaks = array(
        'activity_calories' => 'Activity Tracking',
        'battery_duration' => 'Battery',
        'compat_Android' => 'Compatability',
        'connect_Bluetooth' => 'Connectivity',
        'display_color' => 'Display',
        'notif_apps' => 'Notifications',
        'other_accelerometer' => 'Other Features',
        'reviews' => 'Reviews',
        'link_site' => 'Official Sites',
        'price' => 'Basic Information',
    );
    if(in_array($fields[$row], array_keys($categoryBreaks))) {
        echo "\t<tr class=\"specCategory\"><td colspan=\"" . $colspan . "\">" . $categoryBreaks[$fields[$row]] . "</td></tr>\n";
    }

    // Determine if row highlighting should be enabled
    if(count($validSelections)<=2 && count(array_unique($spec))!=1 && $fields[$row] != 'reviews' && $fields[$row] != 'link_site') {
        $highlight="specHighlight";
    } else {
        $highlight = '';
    }
   
    // Make sure row should be displayed
    $hiddenRows = array(
        'id',
        'shortname',
        'name',
        'category',
        'price_prefix',
        'price_suffix',
    );
    if(!in_array($fields[$row], $hiddenRows)) {

        // New row
        $fieldNames = array(
            'activity_calories' => 'Calories',
            'activity_distance' => 'Distance', 
            'activity_heartRate' => 'Heart rate',
            'activity_sleep' => 'Sleep',
            'activity_steps' => 'Steps',
            'activity_swim' => 'Swim',
            'activity_perspiration' => 'Perspiration',
            'battery_duration' => 'Duration',
            'battery_rechargeable' => 'Rechargeable',
            'compat_Android' => 'Android',
            'compat_iOS' => 'iOS',
            'compat_Mac' => 'Mac',
            'compat_Windows' => 'Windows',
            'connect_Bluetooth' => 'Bluetooth',
            'connect_GPS' => 'GPS',
            'connect_USB' => 'USB',
            'connect_WiFi' => 'Wi-Fi',
            'display_size' => 'Size',
            'display_resolution' => 'Resolution',
            'display_touch' => 'Touch',
            'display_type' => 'Type',
            'other_accelerometer' => 'Accelerometer',
            'other_clock' => 'Clock',
            'other_send' => 'Messaging',
            'other_voice' => 'Voice control',
            'other_waterResistant' => 'Water resistance',
            'other_wirelessSync' => 'Wireless sync',
            'notif_apps' => 'Apps',
            'notif_callerID' => 'Caller ID',
            'notif_email' => 'Email',
            'notif_event' => 'Event',
            'notif_silentAlarm' => 'Silent alarm',
            'notif_SMS' => 'SMS/text',
            'other_downloadableApps' => 'Download apps',
            'other_phoneCalls' => 'Make calls',
            'other_audio' => 'Audio',
            'connect_cell' => 'Cellular',
            'other_camera' => 'Camera',
            'other_UV' => 'UV index',
            'display_color' => 'Color',
            'price' => 'MSRP',
            'release' => 'Release',
        );
        $fieldName = $fieldNames[$fields[$row]];
        echo "\t<tr class=\"" . $fields[$row] . " " . $highlight . "\"><td class=\"specField\" width=\"" . $colwidth . "%\">" . $fieldName . "</td>";
   
        // Data cells
        for($column=0; $column<count($validSelections); $column++) {
       
            // Set cell classes and do general find/replaces
            if($spec[$column] == "Yes") {
                $class = "specYes";
                $spec[$column] = "<i class=\"fa fa-check fa-lg\"></i>";
            } elseif($spec[$column] == "No") {
                $class = "specNo";
                $spec[$column] = "<i class=\"fa fa-close fa-lg\"></i>";
            } elseif($spec[$column] == "n/a") {
                $class = "specNA";
            } else {
                $class = "specNeutral";
                if($spec[$column] == '') {
                    $spec[$column] = "&nbsp;";
                }
            }
           
            // Price row
           
            if($fields[$row] == 'price') {
                $spec[$column] = $specs['price_prefix'][$column] . "$" . $specs['price'][$column] . $specs['price_suffix'][$column];
            }
           
            // Official links row
            if($fields[$row] == 'link_site') {
                $officialSite = htmlspecialchars($spec[$column]);
                unset($spec[$column]);
                $spec[$column] = "<a class=\"specialButton sB1 sB-sm sB-block\" href=\"" . $officialSite . "\" target=\"_blank\" rel=\"nofollow\"><i class=\"fa fa-external-link\"></i>&nbsp; Official site</a>";
            }

            // Reviews row
            $reviewSites = array(
                'pcmag' => 'PC Magazine',
                'forbes' => 'Forbes',
                'cnet' => 'CNET',
                'engadget' => 'Engadget',
                'businessinsider' => 'Business Insider',
                'mashable' => 'Mashable',
                'yahoo' => 'Yahoo',
                'theverge' => 'The Verge',
                'gizmodo' => 'Gizmodo',
                'wired' => 'Wired',
                'consumerreports' => 'Consumer Reports',
                'zdnet' => 'ZDNet',
                'wsj' => 'Wall Sreet Journal',
                'fortune' => 'Fortune',
            );
            if($fields[$row] == 'reviews') {
                $reviewURLs = explode("\n", $spec[$column]);
                unset($spec[$column]);
                $reviewURLsStandard = array();
                foreach($reviewURLs as $reviewURL) {
                    $reviewURLStandard = str_replace('www.', '', $reviewURL); // a search foreach($reviewSites) in $URLparts[2] would be more efficient
                    $reviewURLsStandard[] = $reviewURLStandard;
                }
                sort($reviewURLsStandard);
                $reviewNum = 0;
                foreach($reviewURLsStandard as $reviewURL) {
                    $reviewNum++;
                    $URLparts = explode('/', $reviewURL);
                    $reviewSite = str_replace('.com', '', $URLparts[2]); // a search foreach($reviewSites) in $URLparts[2] would be more efficient
                    $reviewSite = str_replace('.org', '', $reviewSite);
                    $reviewSite = str_replace('.co.uk', '', $reviewSite);
                    $reviewSiteName = $reviewSites[$reviewSite];
                    if($reviewSiteName != '') { // There are more accurate ways to hide blank values, but they aren't working for some reason
                        $spec[$column] .= "<a class=\"specialButton sB00 sB-sm sB-block sB-left sB-marginTop review$reviewNum\" href=\"" . $reviewURL . "\" target=\"_blank\" rel=\"nofollow\"><i class=\"fa fa-external-link\"></i>&nbsp; " . $reviewSiteName . "</a>";
                    }
                    $reviewURLNum++;
                }
            }
           
            // Echo the cell
            echo "<td class=\"".$specs['shortname'][$column]." spec ".$class."\" width=\"" . $colwidth . "%\"><span>".$spec[$column]."</span></td>";
        }
       
        echo "</tr>\n";
       
    }
   
    $row++;
}
?>

    </table>
</div>

<script>
$(document).ready(function(){
    $('#linkToTop').on('click', function(){
        $('html, body').animate({scrollTop: '0px'}, 800);
    }); 
});  
</script>
<br>
<br>
<div id="linkToTop" class="specialButton sB0 sB-xlg"><i class="fa fa-long-arrow-up fa-lg"></i>&nbsp; Top of page</div>
 
The $reviewURLNum error on line 341 is due to you not assigning it a value prior to attempting to increment it.

As for link_site and reviews on line 269, those array keys do not seem to exist in $fieldNames but do in $fields[$row]
Perhaps on line 206 you should break out of the foreach if your check to see that the keys exist in $categoryBreaks fails.

At least that is my understanding of things after having a few drinks and without knowing for sure what your sql query actually returns.
 
Right off the bat I can tell you that your $myTitle error is because you have not assigned it a value (such as $myTitle = '') prior to attempting to add another string to it.
$showAlert_Random must be taken out of the if statement since it is checked for further down the file and therefore might not have been declared.
 
This may be the last one:
ErrorException: Undefined offset: 0 - pages/specs.php:345
Generated By: Unknown Account, 12 minutes ago
Stack Trace
#0 /home3/jes269/public_html/pages/specs.php(345): XenForo_Application::handlePhpError(8, 'Undefined offse...', '/home3/jes269/p...', 345, Array)
#1 /home3/jes269/public_html/library/XenForo/Pages/Specs.php(7): require('/home3/jes269/p...')
#2 [internal function]: XenForo_Pages_Specs::includeFile(Object(NodesAsTabs_ControllerPublic_Page), Object(XenForo_ControllerResponse_View))
#3 /home3/jes269/public_html/library/XenForo/ControllerPublic/Page.php(46): call_user_func_array(Array, Array)
#4 /home3/jes269/public_html/library/XenForo/FrontController.php(347): XenForo_ControllerPublic_Page->actionIndex()
#5 /home3/jes269/public_html/library/XenForo/FrontController.php(134): XenForo_FrontController->dispatch(Object(XenForo_RouteMatch))
#6 /home3/jes269/public_html/index.php(13): XenForo_FrontController->run()
#7 {main}
Request State
array(3) {
["url"] => string(71) "http://wearabletechforums.com/compare/specs/?vs=peak&vs=surge&vs=charge"
["_GET"] => array(1) {
["vs"] => string(6) "charge"
}
["_POST"] => array(0) {
}
}
 
This may be the last one:
And probably the most difficult to figure out since you've made changes to the specs file and so no longer know whats on line 345.
Also, would have to know what the sql query returned in order to figure out how many keys the array has.
Then maybe my little grey cells just might be able to guess at the problem :)
 
Line 345 is:
Code:
                        $spec[$column] .= "<a class=\"specialButton sB00 sB-sm sB-block sB-left sB-marginTop review$reviewNum\" href=\"" . $reviewURL . "\" target=\"_blank\" rel=\"nofollow\"><i class=\"fa fa-external-link\"></i>&nbsp; " . $reviewSiteName . "</a>";

Which array do you need?

Code:
<?php

// Build array of selections
$getSelections=array();
if($_SERVER['QUERY_STRING']!="") {
    $params = explode('&', $_SERVER['QUERY_STRING']);
    foreach ($params as $param) {
        $name_value = explode('=', $param);
        $name = $name_value[0];
        $value = $name_value[1];
        array_push($getSelections, $name_value[1]);
    }
}

// Connect to db
include_once('connect.php');
$connection = mysqli_connect($host, $user, $password, $db) or die();
mysqli_select_db($connection, $db);

// Build list of acceptable shortnames
$acceptableShortnames = array();
$acceptableNames = array();
$shortnameCategory = array();
$acceptableShortnames_SQL = mysqli_query($connection, "SELECT DISTINCT shortname, name, category FROM compare_wearables ORDER BY name") or die(mysqli_error($connection));
while($getShortnames = mysqli_fetch_assoc($acceptableShortnames_SQL)) {
    $acceptableShortnames[] = $getShortnames['shortname'];
    $acceptableNames[$getShortnames['shortname']] = $getShortnames['name'];
    $shortnameCategory[$getShortnames['shortname']] = $getShortnames['category']; // for sidebar.php
}

// Validate selections against acceptable shortnames
$validSelections = array();
foreach($getSelections as $selection) {
    if(in_array($selection, $acceptableShortnames)) {
        $validSelections[] = $selection; 
    }
}

// If no valid selections, pick some randomly
// This would be a good place to limit selections, server-side, if desirable
$showAlert_Random = 0;
if(count($validSelections) < 1) {
    $showAlert_Random = 1;
    $randomSelections = array_rand($acceptableShortnames, 3);
    $validSelections = array();
    foreach($randomSelections as $randomSelection) {
        $validSelections[] = $acceptableShortnames[$randomSelection];
    }
}

// Get specs on valid selections
$validSelectionsStr = implode("','", $validSelections);
$specs_SQL = mysqli_query($connection, "SELECT * FROM compare_wearables WHERE shortname in('".$validSelectionsStr."') ORDER BY name") or die(mysqli_error($db));

// Build data array
$specs = array();
while($item = mysqli_fetch_assoc($specs_SQL)) {
    $fields = array_keys($item); // Can I make this more efficient?
    foreach($fields as $field) {
        $specs[$field][] = $item[$field];
    }
}

// Close connection
mysqli_close($connection);

?>

<div class="bigBanner bB2">

<?php
// Heading for side-by-side comparison
if(count($validSelections)>=2) {
    echo "<h1><i class=\"fa fa-bar-chart\"></i>&nbsp; Wearables Comparison Tool</h1>";
    ?><div><?php
    $myTitle = '';
    for($column=0; $column<count($validSelections); $column++) {
        if($column>0) {
            $myTitle .= " vs.&nbsp;";
        }
        $fullName=str_replace(" ", "&nbsp;", $specs['name'][$column]);
        $myTitle .= $fullName;
        unset($fullName);
    }
    echo $myTitle;
    $myTitle = 'Compare ' . $myTitle; // for HTML <title>
    ?></div><?php
}
// Heading for single item page
else {
    echo "<h1><i class=\"fa fa-info-circle\"></i>&nbsp; " . $specs['name'][0] . "</h1>";
    echo "<div>Features and Specifications</div>";
    $myTitle = $specs['name'][0] . ": Features and Specifications"; // for HTML <title>
}
?>

</div>

<?php

// Show alert if no selections
if($showAlert_Random == 1) {
    echo "<a href=\"/compare/\" class=\"specialButton sB3-inverse sB-xlg sB-left\">
    <strong>You did not select any wearables to compare, so here are 3 selected at random.</strong> Click here to make your own side-by-side comparison.</a>";

}
   
?>

<div class="selectOther-tinyButtons"><a href="/compare/" class="displayWhenResponsive specialButton sB1 sB-tiny"><i class="fa fa-arrow-circle-left"></i>&nbsp; Select other wearables</a></div>


<?php
// Use sticky code if comparison
if(count($validSelections)>=2) {

    echo "\t<script type=\"text/javascript\" src=\"/pages/jquery.sticky.js\"></script>
    <script>
    $(function(){
        if ($(window).width() > 700) {
            $(\".sticky\").sticky({topSpacing:0, getWidthFrom: \"#comparisonSpecs\", responsiveWidth: true});
        }
        var eventFired = 0;
        $(window).on('resize', function() {
            if (!eventFired) {
                if ($(window).width() > 700) {
                    $(\".sticky\").sticky({topSpacing:0, getWidthFrom: \"#comparisonSpecs\", responsiveWidth: true});
                }
            }
        });
    });
    </script>";

} ?>

<div id="comparison">
    <div class="sticky">
        <table class="sticky">
   
<?php

$colwidth = round(100/(count($validSelections)+1),1);

// Head row
echo "\t<tr><th class=\"specField\" width=\"" . $colwidth . "%\">&nbsp;</th>";
for($column=0; $column<count($validSelections); $column++) {
    echo "<th class=\"" . $specs['shortname'][$column] . "\" width=\"" . $colwidth . "%\"><h3>" . $specs['name'][$column] . "</h3></th>";
}
echo "</tr>\n";

// Image row
echo "\t<tr class=\"specImage\"><td class=\"specField\">&nbsp;</td>";
for($column=0; $column<count($validSelections); $column++) {
    echo "<td class=\"".$specs['shortname'][$column]." spec\"><img src=\"/images/compare-".$specs['shortname'][$column].".jpg\" alt=\"".$specs['name'][$column]."\"></td>";
}
echo "</tr>\n";

// Removal button row
if(count($validSelections)>1) {
    echo "\t<tr class=\"removeSelection\"><td class=\"specField\">&nbsp;</td>";
    for($column=0; $column<count($validSelections); $column++) {
        $newURL="/compare/specs/?";
        $subsequent=0;
        foreach($validSelections as $part) {
            if($part!=$specs['shortname'][$column]) {
                if($subsequent>=1) {
                    $newURL=$newURL."&amp;";
                }
                $newURL=$newURL."vs=".$part;
                $subsequent++;
            }
        }
        unset($subsequent);
        echo "<td class=\"".$specs['shortname'][$column]." spec specNeutral\"><a href=\"".$newURL."\" class=\"specialButton sB3-inverse sB-tiny sB-block\"><i class=\"fa fa-ban\"></i> Remove</a></td>";
        unset($removeSelectionURL);
    }
    echo "</tr>\n";
}

?>

        </table>
    </div>
    <table id="comparisonSpecs">

<?php

// Data rows
$row = 0;
$colspan = count($validSelections) + 1;
foreach($specs as $spec) {
       
    // Category rows
    $categoryBreaks = array(
        'activity_calories' => 'Activity Tracking',
        'battery_duration' => 'Battery',
        'compat_Android' => 'Compatability',
        'connect_Bluetooth' => 'Connectivity',
        'display_color' => 'Display',
        'notif_apps' => 'Notifications',
        'other_accelerometer' => 'Other Features',
        'reviews' => 'Reviews',
        'link_site' => 'Official Sites',
        'price' => 'Basic Information',
    );
    if(in_array($fields[$row], array_keys($categoryBreaks))) {
        echo "\t<tr class=\"specCategory\"><td colspan=\"" . $colspan . "\">" . $categoryBreaks[$fields[$row]] . "</td></tr>\n";
    }

    // Determine if row highlighting should be enabled
    if(count($validSelections)<=2 && count(array_unique($spec))!=1 && $fields[$row] != 'reviews' && $fields[$row] != 'link_site') {
        $highlight="specHighlight";
    } else {
        $highlight = '';
    }
   
    // Make sure row should be displayed
    $hiddenRows = array(
        'id',
        'shortname',
        'name',
        'category',
        'price_prefix',
        'price_suffix',
    );
    if(!in_array($fields[$row], $hiddenRows)) {

        // New row
        $fieldNames = array(
            'activity_calories' => 'Calories',
            'activity_distance' => 'Distance', 
            'activity_heartRate' => 'Heart rate',
            'activity_sleep' => 'Sleep',
            'activity_steps' => 'Steps',
            'activity_swim' => 'Swim',
            'activity_perspiration' => 'Perspiration',
            'battery_duration' => 'Duration',
            'battery_rechargeable' => 'Rechargeable',
            'compat_Android' => 'Android',
            'compat_iOS' => 'iOS',
            'compat_Mac' => 'Mac',
            'compat_Windows' => 'Windows',
            'connect_Bluetooth' => 'Bluetooth',
            'connect_GPS' => 'GPS',
            'connect_USB' => 'USB',
            'connect_WiFi' => 'Wi-Fi',
            'display_size' => 'Size',
            'display_resolution' => 'Resolution',
            'display_touch' => 'Touch',
            'display_type' => 'Type',
            'other_accelerometer' => 'Accelerometer',
            'other_clock' => 'Clock',
            'other_send' => 'Messaging',
            'other_voice' => 'Voice control',
            'other_waterResistant' => 'Water resistance',
            'other_wirelessSync' => 'Wireless sync',
            'notif_apps' => 'Apps',
            'notif_callerID' => 'Caller ID',
            'notif_email' => 'Email',
            'notif_event' => 'Event',
            'notif_silentAlarm' => 'Silent alarm',
            'notif_SMS' => 'SMS/text',
            'other_downloadableApps' => 'Download apps',
            'other_phoneCalls' => 'Make calls',
            'other_audio' => 'Audio',
            'connect_cell' => 'Cellular',
            'other_camera' => 'Camera',
            'other_UV' => 'UV index',
            'display_color' => 'Color',
            'price' => 'MSRP',
            'release' => 'Release',
            'link_site' => '',
            'reviews' => '',
        );
        $fieldName = $fieldNames[$fields[$row]];
        echo "\t<tr class=\"" . $fields[$row] . " " . $highlight . "\"><td class=\"specField\" width=\"" . $colwidth . "%\">" . $fieldName . "</td>";
   
        // Data cells
        for($column=0; $column<count($validSelections); $column++) {
       
            // Set cell classes and do general find/replaces
            if($spec[$column] == "Yes") {
                $class = "specYes";
                $spec[$column] = "<i class=\"fa fa-check fa-lg\"></i>";
            } elseif($spec[$column] == "No") {
                $class = "specNo";
                $spec[$column] = "<i class=\"fa fa-close fa-lg\"></i>";
            } elseif($spec[$column] == "n/a") {
                $class = "specNA";
            } else {
                $class = "specNeutral";
                if($spec[$column] == '') {
                    $spec[$column] = "&nbsp;";
                }
            }
           
            // Price row
           
            if($fields[$row] == 'price') {
                $spec[$column] = $specs['price_prefix'][$column] . "$" . $specs['price'][$column] . $specs['price_suffix'][$column];
            }
           
            // Official links row
            if($fields[$row] == 'link_site') {
                $officialSite = htmlspecialchars($spec[$column]);
                unset($spec[$column]);
                $spec[$column] = "<a class=\"specialButton sB1 sB-sm sB-block\" href=\"" . $officialSite . "\" target=\"_blank\" rel=\"nofollow\"><i class=\"fa fa-external-link\"></i>&nbsp; Official site</a>";
            }

            // Reviews row
            $reviewSites = array(
                'pcmag' => 'PC Magazine',
                'forbes' => 'Forbes',
                'cnet' => 'CNET',
                'engadget' => 'Engadget',
                'businessinsider' => 'Business Insider',
                'mashable' => 'Mashable',
                'yahoo' => 'Yahoo',
                'theverge' => 'The Verge',
                'gizmodo' => 'Gizmodo',
                'wired' => 'Wired',
                'consumerreports' => 'Consumer Reports',
                'zdnet' => 'ZDNet',
                'wsj' => 'Wall Sreet Journal',
                'fortune' => 'Fortune',
            );
            if($fields[$row] == 'reviews') {
                $reviewURLs = explode("\n", $spec[$column]);
                unset($spec[$column]);
                $reviewURLsStandard = array();
                foreach($reviewURLs as $reviewURL) {
                    $reviewURLStandard = str_replace('www.', '', $reviewURL); // a search foreach($reviewSites) in $URLparts[2] would be more efficient
                    $reviewURLsStandard[] = $reviewURLStandard;
                }
                sort($reviewURLsStandard);
                $reviewNum = 0;
                foreach($reviewURLsStandard as $reviewURL) {
                    $reviewNum++;
                    $URLparts = explode('/', $reviewURL);
                    $reviewSite = str_replace('.com', '', $URLparts[2]); // a search foreach($reviewSites) in $URLparts[2] would be more efficient
                    $reviewSite = str_replace('.org', '', $reviewSite);
                    $reviewSite = str_replace('.co.uk', '', $reviewSite);
                    $reviewSiteName = $reviewSites[$reviewSite];
                    if($reviewSiteName != '') { // There are more accurate ways to hide blank values, but they aren't working for some reason
                        $spec[$column] .= "<a class=\"specialButton sB00 sB-sm sB-block sB-left sB-marginTop review$reviewNum\" href=\"" . $reviewURL . "\" target=\"_blank\" rel=\"nofollow\"><i class=\"fa fa-external-link\"></i>&nbsp; " . $reviewSiteName . "</a>";
                    }
                }
            }
           
            // Echo the cell
            echo "<td class=\"".$specs['shortname'][$column]." spec ".$class."\" width=\"" . $colwidth . "%\"><span>".$spec[$column]."</span></td>";
        }
       
        echo "</tr>\n";
       
    }
   
    $row++;
}
?>

    </table>
</div>

<script>
$(document).ready(function(){
    $('#linkToTop').on('click', function(){
        $('html, body').animate({scrollTop: '0px'}, 800);
    }); 
});  
</script>
<br>
<br>
<div id="linkToTop" class="specialButton sB0 sB-xlg"><i class="fa fa-long-arrow-up fa-lg"></i>&nbsp; Top of page</div>
 
In line 329 you unset $spec[$column] but then try to add a string to it on line 345
Try simply giving it an empty string on line 329 such as $spec[$column] = '';
 
Top Bottom