I am trying to learn mysqli properly I get most of the functions. One thing left to do is to have proper error reporting across all my layers. I don't understand why the following snippet of code detects an error but won't get the error number nor the error code.
function get_PID_TID_by_PK($con,$ourId)
{
$returned['errno'] ="";
$returned['error'] ="";
//mistake is over here!!!
if(!$stmt = $con->prepare("ELECT gene_name,jgi_protein_id,jgi_transcript_id FROM jgi_transid_protid_match where our_protein_id = ?"))
{
$returned['errno'] = $con->errno;
$returned['error'] = $con->error;
return $returned;
}
if(!$stmt->bind_param('s',$ourId))
{
$returned['errno'] = $stmt->errno;
$returned['error'] = $stmt->error;
return $returned;
}
if(!$stmt->execute())
{
$returned['errno'] = $stmt->errno;
$returned['error'] = $stmt->error;
return $returned;
}
$stmt->bind_result($gene_name,$jgi_protein_id,$jgi_transcript_id);
$stmt->fetch();
$fetchedArray['gene_name'] = $gene_name;
$fetchedArray['jgi_protein_id'] = $jgi_protein_id;
$fetchedArray['jgi_transcript_id'] = $jgi_transcript_id;
//Have to use this hack since query returns an object and not an array and I don't want to make everything object oriented if you don't know what I am talking about just ignore this comment
$returned['assoc'] = $fetchedArray;
return $returned;
}
The mistake is obvious and on the 6th line I wrote ELECT instead of SELECT the program is getting inside that block but the errno and error are null. What am I doing wrong.This code works perfectly fine if I don't break it on purpose.
Are you sure the IF statement is correct?
if(!$stmt = $con->prepare("ELECT gene_name,jgi_protein_id,jgi_transcript_id FROM jgi_transid_protid_match where our_protein_id = ?"))
{
$returned['errno'] = $con->errno;
$returned['error'] = $con->error;
return $returned;
}
Should be
if(($stmt = $con->prepare("ELECT gene_name,jgi_protein_id,jgi_transcript_id FROM jgi_transid_protid_match where our_protein_id = ?")) === FALSE)
{
$returned['errno'] = $con->errno;
$returned['error'] = $con->error;
return $returned;
}
Or split the assignment
$stmt = $con->prepare("ELECT gene_name,jgi_protein_id,jgi_transcript_id FROM jgi_transid_protid_match where our_protein_id = ?");
if($stmt === FALSE)
{
$returned['errno'] = $con->errno;
$returned['error'] = $con->error;
return $returned;
}
I am trying to learn mysqli properly
That's the only mistake you made.
With PDO your code would be... three lines long. And it will report all the errors properly
function get_PID_TID_by_PK($con,$ourId)
{
$stmt = $con->prepare("ELECT gene_name,jgi_protein_id,jgi_transcript_id FROM jgi_transid_protid_match where our_protein_id = ?");
$stmt->execute(array($ourId));
return $stmt->fetch();
}
In the end I decided to go with using http://www.php.net/manual/en/function.set-error-handler.php . I will redesign my code a bit and let the php error handler take care of all the errors and I will make a custom one for my database errors that are happening.
Related
When I try to add something to the sqlite databse the result is always false. Where is the error? I don't get an exception so I think the code is correct by syntax. Please help me
public function add(ChatMessage $chatMessage){
$stmt = $this->db->prepare('INSERT INTO chatmessage(id,authorName,message) VALUES(:id,:authorName,:message)');
$stmt->bindParam(':id',$id);
$stmt->bindParam(':authorName',$authorName);
$stmt->bindParam(':message',$message);
$id = $chatMessage->getID();
$authorName = $chatMessage->getAuthorName();
$message = $chatMessage->getMessage();
$result = $stmt->execute();
if($result == false) return false;
$chatMessage->setID($this->db->lastInsertId());
$chatMessage->setAuthorName($this->db->lastInsertId());
$chatMessage->setMessage($this->db->lastInsertId());
$this->chatMessages[]=$chatMessage;
}
I'm trying to make simple search function but there's an error I cannot find why.
I checked the result SQL query is properly generated. However, execute this prepared statement cause unknown failure. Why this execute() returns false?
public function searchConcept(string $cplx = '', string $name = '', string $desc = '', int $page = 0)
{
$SQL = 'select * from concept ';
$SQL_criteria = array();
// Criteria
if($cplx) { $SQL_criteria[] = 'cplx:cplx'; }
if($name) { $SQL_criteria[] = 'name like :name'; }
if($desc) { $SQL_criteria[] = 'description like :desc'; }
if($SQL_criteria) { $SQL .= 'where '.implode(' and ', $SQL_criteria).' '; }
$SQL .= 'limit :page, 15';
$stmt = $this->db->prepare($SQL);
if($cplx) { $stmt->bindValue(':cplx', $cplx); }
if($name) { $stmt->bindValue(':name', '%'.$name.'%'); }
if($desc) { $stmt->bindValue(':desc', '%'.$desc.'%'); }
$stmt->bindValue(':page', $page*15);
if($stmt->execute()) {
$rst = $stmt->fetchAll(\PDO::FETCH_OBJ);
return $rst;
} else {
throw new DBRFError();
}
}
DBRFError is custom error class that I made.
#
Add 1. ####
I think cplx:cplx doesn't matter. $cplx takes its value something like ">5".
I didn't actually tested that certain situation but I just tested without cplx block and also cause an error.
#
Add 2. ####
I just find the origin of the problem.
$SQL .= 'limit :page, 15'; it cause the error. I do this for pagenation. Without this block, code works well. However, I can't understand why.
You have missing '=' in your where clause. This is the fixed code:
if($cplx) { $SQL_criteria[] = 'cplx=:cplx'; }
I have a function to search for records by course name:
<?php
function searchByCourse()
{
if (isset($_POST["course_title"])) {
//Copy to local var
$course_title = $_POST["course_title"];
$stmt = self::$conn->prepare("SELECT student_id, student_name, course_title FROM student_info WHERE course_title = ?");
$stmt->bind_param("s", $course_title);
$result = $stmt->execute();
if ($result === FALSE) {
$stmt->close();
return FALSE;
} else {
$results_array = array();
$stmt->bind_result($student_id, $student_name, $course_title_found);
while ($stmt->fetch()) {
echo "Fetch! \n";
$row = array();
$row["student_id"] = $student_id;
$row["student_name"] = $student_name;
$row["course_title"] = $course_title;
$results_array[] = $row;
}
$stmt->close();
return $results_array;
}
} else {
return FALSE;
}
}
?>
The code seems to execute fine but when I test it using curl for course_title=Computing it should return 3 results. However the echo "Fetch!" is never displayed. It seems to be that there is nothing for it to fetch. It's driving me a little crazy. I've checked all the var names in the database and they match up fine. Any ideas what I could be doing wrong here?
EDIT:
This method is part of my class DbHandler. $conn is a protected static MySqli connection object created in function__contruct().
called like this:
$db = new DbHandler();
$db->searchByCourse();
I have other database functions that work fine for this design pattern. The function is being called correctly. I have also checked the $_POST["course_title"] and that is being passed correctly.
I have developed a simple REST API using PHP Slim and implemented a simple function which will return a list of track upon matching the album name passed thought REST call.
This is my index.php file for making those rest calls,
http://localhost/my_gallery/v1/tracks/:name
$app->get('/tracks/:name', 'authenticate', function($album_keyword) {
global $user_id;
$response = array();
$db = new DbHandler();
// fetch task
$result = $db->getTracksByName($album_keyword);
if ($result != NULL) {
$response["error"] = false;
$response["album_name"] = $result["album_name"];
$response["track_artist"] = $result["track_artist"];
$response["track_name"] = $result["track_name"];
echoRespnse(200, $response);
} else {
$response["error"] = true;
$response["message"] = "The requested resource doesn't exists";
echoRespnse(404, $response);
}
});
This is the getTracksByName() function for returning a list a tracks after matching the album name,
public function getTracksByName($album_keyword) {
$stmt = $this->conn->prepare(
"SELECT `album`.album_name, `track`.track_artist, `track`.track_name "
. "FROM `category_album` ,`album` , `track` "
. "where `album`.album_id=`track`.album_id AND`album`.`album_name` LIKE ?");
$stmt->bind_param("i", $album_keyword);
if ($stmt->execute()) {
$res = array();
$stmt->bind_result($album_name, $track_artist, $track_name);
$stmt->fetch();
$res["album_name"] = $album_name;
$res["track_artist"] = $track_artist;
$res["track_name"] = $track_name;
$stmt->close();
return $res;
} else {
return NULL;
}
}
Now after making the REST call its returns null values for each track items. Just to mention I've change the SQL query from
... ANDalbum.album_name LIKE ?
to
... ANDalbum.album_id LIKE ?
and its works but for some reason itsn't working with the following query
... ANDalbum.album_name LIKE ?
I'm absolutely new to PHP and any kind of help would be greatly appreciated.
$stmt->bind_param("i", $album_keyword); binds a parameter of type INTEGER. Change to $stmt->bind_param("s", $album_keyword); to bind a parameter of type STRING.
http://php.net/manual/en/mysqli-stmt.bind-param.php
There is two potential issues in your prepared statement code.
First off, you are telling the statement that the parameter is a int:
$stmt->bind_param("i", $album_keyword);
The i indicates Integer. While you want a string (s).
Second issue is that when using LIKE in a prepared statement, you still need the % signs used in a standard LIKE.
For example:
$stmt->bind_param("s", "%$album_keyword%");
i have several database checks with PDO before i insert some values on the DB and i don't know if one try/catch will catch all errors in the nested PDO or if i need one try/catch for every PDO. This is the code i got now:
try {
$db = connect_db();
$q = "query foobar";
$stm = $db->prepare($q);
$stm->bindParam(1, $foobar);
$status = $stm->execute();
if ($stm->rowCount() == 0) {
if ($def == 0) {
$q = "query foobar";
$stm = $db->prepare($q);
$stm->bindParam(1, $foobar);
$stm->bindParam(2, $foobar);
$stm->bindParam(3, $foobar);
$stm->bindParam(4, $foobar);
$status = $stm->execute();
if ($status) {
echo "<script>alert('foobar');window.location.assign('admin.php');</script>";
} else {
echo "<script>alert('foobar');window.location.assign('admin.php');</script>";
die();
}
} else {
$q = "query foobar";
$stm = $db->prepare($q);
$stm->bindParam(1, $nombre);
$status = $stm->execute();
if ($stm->rowCount() == 0) {
$q = "query foobar";
$stm = $db->prepare($q);
$stm->bindParam(1, $foobar);
$stm->bindParam(2, $foobar);
$stm->bindParam(3, $foobar);
$stm->bindParam(4, $user);
$status = $stm->execute();
if ($status) {
echo "<script>alert('foobar.');window.location.assign('admin.php');</script>";
} else {
echo "<script>alert('foobar.');window.location.assign('admin.php');</script>";
die();
}
}
}
} else {
echo "<script>alert('foobar.'); history.back();</script>";
die();
}
} catch (Exception $e) {
// Proccess error
$msg = $e->getMessage();
$timestamp = date("Y-m-d H:i:s");
$line = $e->getLine();
$code = $e->getCode();
handle_error($msg, $timestamp, $line, $code);
die("foobar");
}
PDO::ERRMODE_EXCEPTION
In addition to setting the error code, PDO will throw a PDOException and set its properties to reflect the error code and error information. This setting is also useful during debugging, as it will effectively "blow up" the script at the point of the error, very quickly pointing a finger at potential problem areas in your code (remember: transactions are automatically rolled back if the exception causes the script to terminate).
Exception mode is also useful because you can structure your error handling more clearly than with traditional PHP-style warnings, and with less code/nesting than by running in silent mode and explicitly checking the return value of each database call.
So, one is enough