How to skip non-object error in PHP mysqli? - php

When having an error in SQL syntax in classic PHP mysql, the query will not take place without any other effect. But in mysqli, it will kill the PHP script with Fatal error
mysql_query("SELECT title, misspelled_column FROM posts");
$mysqli->query("SELECT title, misspelled_column FROM posts");
In the first case, it will show the other queries and php output; but the second case kills the script by
Fatal error: Call to a member function fetch_assoc() on a non-object
The problem is related to non-object returned by false query. I can skip this error by
if($result){$row = $result->fetch_assoc();}
but my question is that why I did not need this check in classic mysql? With a more advanced system, one expects new features not missing what we had.

An error generated by MySQL should not be stopping execution. In fact, you can have your script show you any SQL errors by using $mysqli->error (assuming $mysqli is your database connection, like in your example). However, what may be happening is that your mysqli error causes a particular object not to be created, and then calling a method on that object will create a fatal PHP error. For example:
$dbconn = new mysqli("localhost", $username, $password, $dbname);
$stmt = $dbconn->prepare("bluh"); // not a valid statement. fails to create a mysqli statement object in $stmt.
echo($dbconn->error); // your script is still running, and this will show your MySQL syntax error.
$stmt->execute();
This will die not because you made an SQL error, but because $stmt was null and didn't have the expected execute() method. So like everyone else has said, check your logs and see what the actual error is.
Using # to ignore errors is going to be hit-or-miss until you figure out which specific command is creating the error.
update: If you know that the error is in the query, then you could check to see whether the query succeeded before you try to do anything with it. One way is to check the error parameter; another is to check to make sure that it actually returned the kind of object you want.
Here are examples of both:
$result = $db->query("select firstname, lastname from people where firstname = 'egbert';");
if($db->error == '') {
// the query worked, so fetch results from $result and do stuff with them.
}
else {
// the query didn't work, so don't try to do anything with $result
}
// alternately:
if(gettype($result) == "object") {
// the query worked.
}
else {
// it didn't.
}

A SQL error doesn't kill mysqli in my experience. I suspect you actually have a PHP error in the relevant statement. Check your error log.
In PHP, you can use # to suppress errors. It's a bad idea to use it here. But if that's what you really want, it's documented at http://php.net/manual/en/language.operators.errorcontrol.php.

Related

Why PDO connection sowing "SQLSTATE[HY000]: General error"?

I am using pdo connection. I am trying to run a delete query but it is showing this message in the browser
*SQLSTATE[HY000]: General error*
Here is my query:
$user_id = $_POST['user_id']; $result = query($conn, "DELETE FROM user WHERE user_id = '$user_id'");
I don't know why happening this. Any kind of help will be appreciated.Thanks
I think there is a query() function does not exists in PHP .. It should be mysql_query or mysqli_query
Using Mysql query is bad because it is depreciated in Updated version of php
$result = mysqli_query($conn, "DELETE FROM user WHERE user_id = '$user_id'");
//So using mysqli :)
$result = mysqli_query($conn, "DELETE FROM user WHERE user_id = '$user_id'");
Per MySQL 5.5.35 source code, sql/sql_prepare.cc:
bool
Reprepare_observer::report_error(THD *thd)
{
/*
This 'error' is purely internal to the server:
- No exception handler is invoked,
- No condition is added in the condition area (warn_list).
The diagnostics area is set to an error status to enforce
that this thread execution stops and returns to the caller,
backtracking all the way to Prepared_statement::execute_loop().
*/
thd->stmt_da->set_error_status(thd, ER_NEED_REPREPARE,
ER(ER_NEED_REPREPARE), "HY000");
m_invalidated= TRUE;
return TRUE;
}
It appears that your error (SQL state HY000) will happen when there is a wrong sequence of prepare/execute statements. Double-check our logic to make sure you are properly using prepared statements, e.g properly fetching all of the results after the call to query() before calling it again.
If you cannot figure it out, isolate the problem to a minimal, complete, and verifiable example (https://stackoverflow.com/help/mcve), and post the code here.
UPDATE:
Does the problem go away (or do you at least get a meaningful error message) if you do
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
prior to the query?

Using PHP in XAMPP: can create db but cannot create tables

I'm a beginner programmer, and I've installed XAMPP with the intention of learning a bit of PHP. I have a working knowledge of SQL.
I've been following the PHP tutorial at w3schools. The problem I am currently having is this: I'm using the script here to create a database and a table within it. What I'm using is almost verbatim, except I've replaced the user with "root" and I've deleted the password.
After running the script through the browser, the database my_db appears in the datafile for mysql in XAMPP.
However, there is no sign of a table, and when I try to select the table, I get
Table 'my_db.persons' doesn't exist
What is going on? Is there something wrong with the code I took verbatim, or is it something with permissions?
It's weird that the database is created but not a table...
What has happenned is that your "CREATE TABLE" will have failed.
Get into the habit of checking for errors after EVERY mySQL query (in your code): there are some times you can ignore errors, but it's rare. So program alonghte lines of:
Create query: $sql =
Set parameters: $aParams = (or bind paramters)
Execute query
If errors
If debug: Show error and query
If live: Log error and query
I'm not giving the solution is code, as one problem with the tutorial you follow is that it uses mysql_() functions that are going to be depreciated shortly. You should use PDO (PHP Database Objects) or mysqli() functions otherwise your code will not work in a few releases time.
With PDO, you can set error handling to use exceptions, and you wrap every call in try {} catch {} and this makes the habit of catching and reporting errors very easy.
$sql = 'CREATE TABLE....';
$aParams = array(
':param_name' => $param_value,
':param_name2' => $param_value2
);
try {
$stmnt = $db->prepare($sql);
$stmnt->execute($aParams);
$stmnt = null;
} catch (Exception $e) {
// Error log here; $e contins line of error and the actual error, you have $sql and $aParams
LogDBError($e, $sql, $aParams);
}

php mysql get row

I am trying to use the mysqli to access a mysql database and a table called phptest, with the code below. I am trying to check if row is = 0 or something else but it does not echo anything. What is wrong with the code?
$mysqli = new mysqli("localhost", "root", "", "phptest");
if (!$mysqli) {
echo "Can't connect to MySQL Server. Errorcode: %s\n". mysqli_connect_error();
exit;
}
$query = "SELECT `id` FROM `test` WHERE `email`='example#hotmail.com' AND `password`='5f4dcc3b5aa765d61d8327deb882cf99'";
$query_run = $mysqli->query($query);
$row_cnt = $query_run->num_rows;
if ($row_cnt==0) {
echo 'wrong..';
} else {
echo 'correct!';
}
EDIT: edited the variable in the if statement. I have runned the query directly in the mysql panel in the tabel. I get the right row count then. Why doesnt it work in php ?
Although you are checking for an undefined variable $row_count (which should be $row_cnt, that isn't your immediate problem (you should still fix this). You are getting a fatal error either because:
Your query is failing. Your query may be failing because of a missing field on the table or indeed you are missing the actual table in the database. The query will return FALSE if it fails, but you aren't checking for that, instead you try to access a property of the result. If the query fails, there is no result object, it is a boolean FALSE and will produce a fatal error something like Fatal Error: Trying to access a property of a none object.
You don't have the MySQLi library configured for your PHP installation
To further debug you should turn on error reporting as below, or consult your server's error log.
error_reporting(E_ALL);
ini_set('display_errors', '1');
One thing is that you defined $row_cnt and then checked for $row_count, but that's just a quick look at your program, so there might be something else wrong too.

my sql query failing and yet returns no mySQL errors

I have been writing php and mySQL functions all day and as I was writing the simplest part of my project I have hit a wall.
The function should simply count how many entries are in the database and return that number (If there is a more simple way please let me know, this is my first php + mysql project)
Here is the code:
function quoteCount(){
global $db;
$totalQuoteNum = array();
$query = "SELECT * FROM Quotes";
$result_set = mysqli_query($db, $query)
or die ("Query $query failed ".mysqli_error($db)); //fails here
$totalQuoteNum = mysql_num_rows($result_set)
or die ('couldnt count rows'.mysqli_error($db));
echo 'COUNTED EVERYTHING!!!';
return $totalQuoteNum;
};
Now when the die statement prints I get the string but not the mysqli error.
Things I have tried and ruled out:
$db is correct
query works in mysql
I wasnt sure if the database was connected, so I added the connect inside this function and stil nothing.
Any ideas? From what I see it should work and its not giving me any error to work from. Please help!
Based on the comments, it seems as though $db is the database name.
Functions such as mysqli_query() expect a database link (resource), not simply the database name.
This resource is created by constructing a new mysqli object. Following your procedural style, use mysqli_connect().

PDO Unbuffered queries

I'm trying to get into PDO details. So I coded this:
$cn = getConnection();
// get table sequence
$comando = "call p_generate_seq('bitacora')";
$id = getValue($cn, $comando);
//$comando = 'INSERT INTO dsa_bitacora (id, estado, fch_creacion) VALUES (?, ?, ?)';
$comando = 'INSERT INTO dsa_bitacora (id, estado, fch_creacion) VALUES (:id, :estado, :fch_creacion)';
$parametros = array (
':id'=> (int)$id,
':estado'=>1,
':fch_creacion'=>date('Y-m-d H:i:s')
);
execWithParameters($cn, $comando, $parametros);
my getValue function works fine, and I get the next sequence for the table. But when I get into execWithParameters, i get this exception:
PDOException: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in D:\Servidor\xampp_1_7_1\htdocs\bitacora\func_db.php on line 77
I tried to modify the connection attributes but it doesn't work.
These are my core db functions:
function getConnection() {
try {
$cn = new PDO("mysql:host=$host;dbname=$bd", $usuario, $clave, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
));
$cn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
return $cn;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
function getValue($cn, $comando) {
$resul = $cn->query($comando);
if (!$resul) return null;
while($res = $resul->fetch()) {
$retorno = $res[0][0];
break;
}
return $retorno;
}
function execWithParameters($cn, $comando, $parametros) {
$q = $cn->prepare($comando);
$q->execute($parametros);
if ($q->errorInfo() != null) {
$e = $q->errorInfo();
echo $e[0].':'.$e[1].':'.$e[2];
}
}
Somebody who can shed a light for this? PD. Please do not suggest doing autonumeric id, cause i am porting from another system.
The issue is that mysql only allows for one outstanding cursor at a given time. By using the fetch() method and not consuming all the pending data, you are leaving a cursor open.
The recommended approach is to consume all the data using the fetchAll() method.
An alternative is to use the closeCursor() method.
If you change this function, I think you will be happier:
<?php
function getValue($cn, $comando) {
$resul = $cn->query($comando);
if (!$resul) return null;
foreach ($resul->fetchAll() as $res) {
$retorno = $res[0];
break;
}
return $retorno;
}
?>
I don't think PDOStatement::closeCursor() would work if you're not doing a query that returns data (i.e. an UPDATE, INSERT, etc).
A better solution is to simply unset() your PDOStatement object after calling PDOStatement::execute():
$stmt = $pdo->prepare('UPDATE users SET active = 1');
$stmt->execute();
unset($stmt);
The problem seems to be---I'm not too familiar with PDO--- that after your getValue call returns, the query is still bound to the connection (You only ever ask for the first value, yet the connection returns several, or expects to do so).
Perhaps getValue can be fixed by adding
$resul->closeCursor();
before the return.
Otherwise, if queries to getValue will always return a single (or few enough) value, it seems that using fetchAll will be preferred.
I just spend 15 minutes googling all around the internet, and viewed at least 5 different Stackoverflow questions, some who claimed my bug apparently arose from the wrong version of PHP, wrong version of MySQL library or any other magical black-box stuff...
I changed all my code into using "fetchAll" and I even called closeCursor() and unset() on the query object after each and every query. I was honestly getting desperate! I also tried the MYSQL_ATTR_USE_BUFFERED_QUERY flag, but it did not work.
FINALLY I threw everything out the window and looked at the PHP error, and tracked the line of code where it happened.
SELECT AVG((original_bytes-new_bytes)/original_bytes) as saving
FROM (SELECT original_bytes, new_bytes FROM jobs ORDER BY id DESC LIMIT 100) AS t1
Anyway, the problem happened because my original_bytes and new_bytes both where unsigned bigints, and that meant that if I ever had a job where the new_bytes where actually LARGER than the original_bytes, then I would have a nasty MySQL "out of range" error. And that just happened randomly after running my minification service for a little while.
Why the hell I got this weird MySQL error instead of just giving me the plain error, is beyond me! It actually showed up in SQLBuddy (lightweight PHPMyAdmin) when I ran the raw query.
I had PDO exceptions on, so it should have just given me the MySQL error.
Never mind, the bottom line is:
If you ever get this error, be sure to check that your raw MySQL is actually correct and STILL working!!!
A friend of mine had very much the same problem with the xampp 1.7.1 build. After replacing xampp/php/* by the 5.2.9-2 php.net build and copying all necessary files to xampp/apache/bin it worked fine.
If you're using XAMPP 1.7.1, you just need to upgrade to 1.7.2.

Categories