I have 3 PHP files: an index.php, a config.php w/ MySQL database definitions and a functions.php file with three separate functions. When only one of the functions is called in the index file, things work fine. When I add just one of the other two, however, things stop working.
Using the following example/files, I get this error message where the second function falls in the index.php code:
Error: Fatal error: Call to a member function query() on a non-object in...line 37, which corresponds to the DB query in that second function-- the get_chapter_dollars function.
I'm sure it's something simple, but what am I missing, here? Why is that second function causing problems?
CONFIG.PHP
<?php
define("BASE_URL","/dayofgiving/");
define("ROOT_PATH",$_SERVER["DOCUMENT_ROOT"] . "/dayofgiving/");
// Set variables for the database.
define("DB_HOST", "localhost");
define("DB_NAME", "cdwyer_dspdog");
define("DB_PORT", "1234");
define("DB_USER", "user");
define("DB_PASS", "pass");
FUNCTIONS.PHP
<?php
require_once($_SERVER["DOCUMENT_ROOT"] . "/dayofgiving/inc/config.php");
function get_state_stats() {
require_once(ROOT_PATH . "inc/db.php");
try {
$results = $db->query("
SELECT abb, fullname, dollars, alumnidollars, ugdollars, donors, alumnidonors, ugdonors
FROM dog_states");
$maxDollars = $db->query("
SELECT MAX(dollars)
FROM dog_states;
");
} catch (Exception $e) {
echo "Data coudn’t be found.";
exit;
}
$maxDollars = intval($maxDollars->fetchColumn(0));
$stateInfo=array();
while ($row = $results->fetch(PDO::FETCH_ASSOC)) { // Will return boolean(false) when condition is no longer met.
$stateAbb = $row["abb"];
$thisDollars = $row["dollars"];
$stateInfo[$stateAbb] = $row; // Loops through all states/rows one at a time, and adds all properties to the stateInfo variable w/ abbreviation as key.
$stateInfo[$stateAbb]["opacity"] = ((($thisDollars / $maxDollars)*.5)+.5);
}
return $stateInfo;
}
function get_chapter_dollars() {
require_once(ROOT_PATH . "inc/db.php");
try {
$dollarResults = $db->query("
SELECT abb, fullname, dollars
FROM dog_chapters
ORDER BY dollars DESC
LIMIT 5");
} catch (Exception $e) {
echo "Data coudn’t be found.";
exit;
}
$chapterDollars=array();
while ($row = $dollarResults->fetch(PDO::FETCH_ASSOC)) { // Will return boolean(false) when condition is no longer met.
$chapterDollars[] = $row; // Loops through all (ie, top 5) chapters/rows one at a time, and adds all properties to the chapterDollars variable w/ number as key.
}
return $chapterDollars;
}
function get_chapter_donors() {
require_once(ROOT_PATH . "inc/db.php");
try {
$donorResults = $db->query("
SELECT abb, fullname, donors
FROM dog_chapters
ORDER BY donors DESC
LIMIT 5");
} catch (Exception $e) {
echo "Data coudn’t be found.";
exit;
}
$chapterDonors=array();
while ($row = $donorResults->fetch(PDO::FETCH_ASSOC)) { // Will return boolean(false) when condition is no longer met.
$chapterDonors[] = $row; // Loops through all (ie, top 5) chapters/rows one at a time, and adds all properties to the chapterDollars variable w/ number as key.
}
return $chapterDonors;
}
?>
INDEX.PHP (portion)
<?php require_once($_SERVER["DOCUMENT_ROOT"] . "/dayofgiving/inc/config.php"); ?>
<?php require_once(ROOT_PATH . "db/functions.php"); ?>
<?php $tempStateStats = get_state_stats() ?>
var jsonStates = <?php echo json_encode($tempStateStats); ?>;
<?php $returnChapterDollars = get_chapter_dollars() ?>
<?php echo $returnChapterDollars[0]["abb"];?>
I've had issues with require_once working correctly with my version of PHP (5.3.3). For the purpose of testing try changing it to require or include for each instance on the page and see if it works.
Related
This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 4 years ago.
I want to show all the records from the DB on my website, it's a PDO built website. I want it to show all the records so you can see what's in the DB.
This is how my DB looks like
The connection is set up in a different document called config.php
<?php
date_default_timezone_set('Europe/Amsterdam');
error_reporting(E_ALL & ~ E_DEPRECATED);
ini_set('display_errors', 'ON');
$CONFIG = array();
$CONFIG['root'] = '/home/tom/public_html';
$CONFIG['rootwebsite'] = '/home/tom/public_html';
$CONFIG['website'] = 'https://###';
$CONFIG['dbhost'] = 'localhost';
$CONFIG['dbuser'] = '####';
$CONFIG['dbpass'] = '####';
$CONFIG['dbdatabase'] = 'tom';
?>
This is the code I have in a php document and tried using. The problem is it won't show anything on my website (this is a different file than the file my website is):
<?php
class Forum {
private $dbh; //dbh = database handler.
public function __construct($database) {
$this->dbh = $database;
}
public function getForum() {
$getTopic = $dbh->prepare("SELECT * FROM topics ORDER BY id DESC");
$getTopic->execute();
$topics = $getUTopic->fetchAll();
foreach ($topics as $topic) {
echo $topic['onderwerp'] . '<br />';
}
}
}
You are not calling the right $connection variable. It should be $this->dbh
$getTopic = $this->dbh->prepare("SELECT * FROM topics ORDER BY id DESC");
Also you are mixing the variables after execute(). You should use easy to remember variables.
public function getForum() {
try {
$getTopic = $this->dbh->prepare("SELECT * FROM topics ORDER BY id DESC");
$getTopic->execute();
$topics = $getTopic->fetchAll();
foreach ($topics as $topic) {
echo $topic['onderwerp'] . '<br />';
}
} catch (PDOException $pdoEx) {
echo $pdoEx->getMessage();
exit;
} catch (Exception $ex) {
echo $ex->getMessage();
exit;
}
}
Also since you are not passing any variable to your query, there is no point of using prepare(). Just call query() instead.
For error reporting add,
error_reporting(E_ALL); #place at the top of the script
Also you should consider using a proper IDE like PHPstorm or Netbeans, as they would easily point out unsed variables
As suggested by #adpro, here is a link, to help with debugging
Hey guys so i really have a problem in php and i have been working on it for like an hour and i can get it to work. So in my database i have two tables:
usuarios and menus
So each user have a menu assigned like this:
usuarios
id email ....... menus
1 email ...... 1,2,3,4
where 1,2,3,4 is text that i will explode and convert it into an array so latter i can get the menus checking the menu id's.
menus
id url .....
1 profile ..........
2 messages ..........
3 log out ..........
4 support ..........
I dont know why it is not working, please help.
<?php
if (!empty($_SESSION['id'])) {
include_once "database.php";
$section = !empty($_GET['s']);
try {
$stmt = $db->prepare("SELECT * FROM usuarios WHERE id=:usuid");
$stmt->execute(array(':usuid'=>$_SESSION['id']));}
// Checks the user id from his session (session has been already started in headers)
if($stmt->rowCount() > 0){
$row = $stmt->fetch();
$menus = $row['menus'];
//Gets the menus
$menus = explode(",", $menus);
//Converts the text into an array.
$i = 0;
$menusize = sizeof($menus);
//Checks how big is $menus array
$menusize = $menusize -1;
//This is because $i=0 and not 1
while ($i == $menusize) {
try{
$stmt = $db->prepare("SELECT * FROM menus WHERE id=:menus");
$stmt->execute(array(':menus'=>$menus[$i]));
$row = $stmt->fetch();
if ($section==$row['url']) {
echo '<li class="liselected"><i class="'.$row['icon'].'"></i><p>'.$row['name'].'</p></li>';
}else{
echo '<li class="menuelement"><i class="'.$row['icon'].'"></i><p>'.$row['name'].'</p></li>';
}
$i++;
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}
//Here is the problem, in this while
} else {
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}else{
header("Location:index.php");
}
?>
I have checked and what happends is that $i doesnt seems to be incrementing, i have been working on it but nothing seems to do it.
Thank you all for your support!
You should do it a little bit differently altogether, like storing the menu's in different rows but for now:
<?php
if (!empty($_SESSION['id'])) {
include_once "database.php";
$section = !empty($_GET['s']);
try {
# When you set the $_SESSION['id'] and you're sure it's sanitized you don't have to prepare a query. Instead execute it directly.
# Preparing is useful for user submitted data or running the same query more then once with different values (seen below)
$stmt = $db->prepare("SELECT * FROM usuarios WHERE id=:usuid");
$stmt->execute(array(':usuid'=>$_SESSION['id']));
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
if($stmt->rowCount() > 0){
// This part of the code does not match your description of your database.
$row = $stmt->fetch();
$menu = explode(",", $row['menus']);
// end
$stmt = $db->prepare("SELECT * FROM menus WHERE id=:menus");
try{
foreach($menu as $value){
$stmt->execute(array(':menus'=>$value));
$row = $stmt->fetch();
$css_class = ($section == $row['url']) ? 'liselected' : 'menuelement';
echo '<li class="'.$css_class.'"><i class="'.$row['icon'].'"></i><p>'.$row['name'].'</p></li>';
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}
} else {
header("Location:index.php");
}
?>
Please note that I only prepared the query once, this is the proper way to do it. Preparing takes server performance, but once prepared you can rebind the values.
Also, I changed the loop to a foreach loop, easier to maintain.
There where also some bracket issues in the code, my advice always code in the same way so these issues are easy to spot.
I get null values when I run this code
$dataArray = mysql_query ("SELECT * from _$symbol order by date DESC limit 10;");
while ($ArrayData = mysql_fetch_assoc($dataArray)) {
$dayData [] = $ArrayData;
}
$todaysdate = $dayData[0]['date'];
$volPercentAVG = $dayData[0]['volume'] / $dayData[0]['_50dayVol'];
mysql_query ("update _$symbol set volPercentAvg=$volPercentAVG WHERE date=$todaysdate;");
It does not return anything, I am not sure I am approaching the MDarray correctly? I have triple checked the column names.
Anywhere to do with this would be helpfull
Thanks.
#Fred-ii- YOU DID IT! Can I or you make this an answer so I can vote for it? If I can I dont see how. – illcrx
Posting my comment as the answer in order to close the question.
If your date column contains any spaces or dots etc. then change WHERE date=$todaysdate
to/and quoting it WHERE date='$todaysdate'
For example: 2014-10-06 22:59:52
Would explain why you were not getting results.
However, I'm quite surprised/baffled that MySQL did not throw you a syntax error, bizarro.
Don't have time to read your entire bit right now, but I can give you my test method from our standard mysqli execution set:
print_r($Record);
This will allow you to see the structure and possibly where your error lies.
I'll also give you our framework which can be very useful (which is why we have it! LOL). Example framework (two functions) to make it easier to use mysqli in php with two lines for each query. It also allows for CLI or web output and debugging which will dump the query (so you can run it) and shows a print_r function to show results.:
This goes at the top:
define('DEBUG', false);
define('CLIDISPLAY', false);
if (CLIDISPLAY) {
define('PRE', '');
define('PRE_END', '');
} else {
define('PRE', '<pre>');
define('PRE_END', '</pre>');
}
require_once("/etc/dbconnect.php");
$DBLink = new mysqli($VARDB_server, $VARDB_user, $VARDB_pass, $VARDB_database, $VARDB_port);
if ($DBLink->connect_errno) {
printf(PRE . "Connect failed: %s\n" . PRE_END, $DBLink->connect_error);
exit();
}
Be sure you have a normal php file at /etc/dbconnect.php with your credentials in it (do not put these in a web folder in case php fails one day and exposes your passwords! LOL). Note that this file can then be shared and loaded only once. It should invoke
# Sample execution
$Query = "select * from vicidial_users where user='6666' and active='Y' limit 1";
$Records = GetData($DBLink, $Query);
print_r($Records[0]); // Single record return access via [0] to access a field named "id": $Records[0]['id']
// Multiple record return access via array walking
foreach ($Records as $Record) {
print_r($Record);
}
$Query = "update vicidial_users set active='Y' where user='6666' limit 1";
UpdateData($DBLink, $Query);
Functions (can be loaded from the credentials file or within your working file or put in a "functions.php" file and "require_once('functions.php');".
function GetData($DBLink, $Query) {
if (DEBUG) {
echo PRE . "Query: $Query\n" . PRE_END;
}
if ($Result = $DBLink->query($Query)) {
if (DEBUG) {
printf(PRE . "Affected rows (Non-Select): %d\n" . PRE_END, $DBLink->affected_rows);
}
while ($Record = $Result->fetch_assoc()) {
$ReturnData[] = $Record;
}
return $ReturnData;
} else {
if (DEBUG) {
printf(PRE . "Errormessage: %s\n", $DBLink->error);
printf("Affected rows (Non-Select): %d\n", $DBLink->affected_rows);
echo "No Records Returned\n" . PRE_END;
}
return false;
}
}
function UpdateData($DBLink, $Query) {
if (DEBUG) {
echo PRE . "Query: $Query\n" . PRE_END;
}
if ($Result = $DBLink->query($Query)) {
if (DEBUG) {
printf(PRE . "%s\n", $DBLink->info);
printf("Affected rows (Non-Select): %d\n" . PRE_END, $DBLink->affected_rows);
}
return;
} else {
if (DEBUG) {
printf(PRE . "Errormessage: %s\n", $DBLink->error);
printf("Affected rows (Non-Select): %d\n", $DBLink->affected_rows);
echo "No Records Returned\n" . PRE_END;
}
return;
}
}
i wrote a PHP Function but it does nothing at a specific point.. im new to php and my english is bad, sorry for that.
<?php
function SQLwriteRecent($id, $title, $link) {
$con=mysqli_connect("localhost","","","");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$count = mysqli_query($con,"SELECT count FROM recent WHERE sc_stream='$id'");
if(!isset($count)) {
try {
mysqli_query($con,"INSERT INTO recent (title, link, sc_stream, count) VALUES ('$title', '$link', '$id',$count)");
mysqli_close($con);
return 1;
} catch(Exception $e) {
return 0;
}
} else {
try {
// ------ SHOW HERE!!!! ------------ //
mysqli_query($con,"UPDATE recent SET count=$count WHERE sc_stream='$id'");
mysqli_close($con);
return 2;
} catch(Exception $e) {
return 0;
}
}
}
?>
the code runs every time until a specific point (i marked it in the code with // ------ SHOW HERE!!!! ------------ //)
in the sql table, currently there is no entry. so i should create a new row
whats wrong with that code?! :(
Your script wont insert a new row, because you have defined $count, it is a mysqli_result object. You have to check if there is a row, something you could do like this;
Instead of
if(!isset($count))
use
if(mysqli_num_rows($count) == 0)
Some explanation:
You have this in your code:
if(!isset($count)) {
This checks that your variable has been set, nor is empty, false, or 0. This condition ALWAYS return true because the variable is setted in line before, use mysqli_nuw_rows instead
Combining what other people have said, and looking at the logic of what you're doing, it looks like you have a few fundamental issues:
I've tweaked some variable names to make it clearer what you're getting an peppered the code with comments that describe the issues.
I've ignored the SQL injection issues.
<?php
function SQLwriteRecent($id, $title, $link) {
$con=mysqli_connect("localhost","","","");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$countQuery = mysqli_query($con,"SELECT count FROM recent WHERE sc_stream='$id'");
$numberOfRowsReturnedByQuery = mysqli_num_rows($count);
if ( $numberOfRowsReturnedByQuery > 0 ) {
$valueOfCountInQuery = $countQuery [0]['count'];
}
if( $numberOfRowsReturnedByQuery == 0) {
try {
// In this situation it looks like you want to set up a value in "recent" - I.E. you didn't have a record.
// But think about it for a second - if you had no record in "recent" then how could "$valueOfCountInQuery" possibly be set?
mysqli_query($con,"INSERT INTO recent (title, link, sc_stream, count) VALUES ('$title', '$link', '$id',$valueOfCountInQuery )"); // makes no sense to use "$valueOfCountInQuery" - maybe you mean "0" (zero)
mysqli_close($con);
return 1;
} catch(Exception $e) {
return 0;
}
} else {
try {
// In this situation it looks like you want to update the value in "recent" - I.E. you DID have a record and you want to change it.
// But think about it for a second - the value of "$valueOfCountInQuery" is the value that you got from "count" on "recent". You are setting it to the same value that's already in there!
// ------ SHOW HERE!!!! ------------ //
mysqli_query($con,"UPDATE recent SET count=$valueOfCountInQuery WHERE sc_stream='$id'"); // redundant
mysqli_close($con);
return 2;
} catch(Exception $e) {
return 0;
}
}
}
?>
You did a mistake here, query returns array
try this
mysqli_query($con,"UPDATE recent SET count=$count[0]['count'] WHERE sc_stream='$id'");
You have set:
count=$count
but
$count = mysqli_query($con,"SELECT count FROM recent WHERE sc_stream='$id'");
Specify a proper value for count not a resource
to retrieve the actual result of the query you have to do something like
if ( $result = $con->query($sql)){ //perform the query
if ($result->num_rows == 1){
if ($row = $result->fetch_assoc()){
$count = $row['count'];
}
else{
echo "couldn't fetch result row";
}
else {
echo "expected one result row, got ".$result->num_rows;
}
}
else {
echo "query failed:".$sql;
echo $con->errno.' '.$con->error;
}
// if you have more than one result row
if ( $result = $con->query($sql))
while ($row = $result->fetch_assoc()){ //loop through the result(s)
$count = $row['count']
}
// procedural style
if ( $result = mysqli_query($con,$sql))
while($row = mysqli_fetch_assoc($result)){
I just switched to PDO from mySQLi (from mySQL) and it's so far good and easy, especially regarding prepared statements
This is what I have for a select with prepared statement
Main DB file (included in all pages):
class DBi {
public static $conn;
// this I need to make the connection "global"
}
try {
DBi::$conn = new PDO("mysql:host=$dbhost;dbname=$dbname;charset=utf8", $dbuname, $dbpass);
DBi::$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
DBi::$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo '<p class="error">Database error!</p>';
}
And in my page:
try {
$sql = 'SELECT pagetitle, pagecontent FROM mypages WHERE pageid = ? LIMIT 1';
$STH = DBi::$conn->prepare($sql);
$STH->execute(array($thispageid)); // $thispageid is from a GET var
}
catch(PDOException $e) {
echo '<p class="error">Database query error!</p>';
}
if ($STH) { // does this really need an if clause for it self?
$row = $STH->fetch();
if (!empty($row)) { // was there found a row with content?
echo '<h1>'.$row['pagetitle'].'</h1>
<p>'.$row['pagecontent'].'</p>';
}
}
It all works. But am I doing it right? Or can I make it more simple some places?
Is using if (!empty($row)) {} an ok solution to check if there was a result row with content? Can't find other decent way to check for numrows on a prepared narrowed select
catch(PDOException $e) {
echo '<p class="error">Database query error!</p>';
}
I would use the opportunity to log which database query error occurred.
See example here: http://php.net/manual/en/pdostatement.errorinfo.php
Also if you catch an error, you should probably return from the function or the script.
if ($STH) { // does this really need an if clause for it self?
If $STH isn't valid, then it should have generated an exception and been caught previously. And if you had returned from the function in that catch block, then you wouldn't get to this point in the code, so there's no need to test $STH for being non-null again. Just start fetching from it.
$row = $STH->fetch();
if (!empty($row)) { // was there found a row with content?
I would write it this way:
$found_one = false;
while ($row = $STH->fetch()) {
$found_one = true;
. . . do other stuff with data . . .
}
if (!$found_one) {
echo "Sorry! Nothing found. Here's some default info:";
. . . output default info here . . .
}
No need to test if it's empty, because if it were, the loop would exit.