Getting the MySQLi error in class extension - php

I've got a custom database class which extends the MySQLi class.
It connects to the database using parent in the __construct method.
Below is the portion of the query if the query is not successful, how do I return the error from the server?
$query = parent::query($querystr, $resultmode);
if (!$query) {
$error = str_replace(
'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use',
'Syntax Error',
mysqli_error(self::getInstance()));
\core\debug::sqlerrorlog($error);
} else {
\core\debug::sqlSuccess();
}

According to docs, you just need to do $this->error.
As I understand, your problem now is that you don't pass a correct intsance of mysqli to mysql_error - maybe self::getInstance() is not doing what it supposed to, but I can't tell from what I see.

Related

PHP MySQL - Error trying to update record [duplicate]

This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 5 years ago.
I'm trying to get my head around MySQli and I'm confused by the error reporting.
I am using the return value of the MySQLi 'prepare' statement to detect errors when executing SQL, like this:
$stmt_test = $mysqliDatabaseConnection->stmt_init();
if($stmt_test->prepare("INSERT INTO testtable VALUES (23,44,56)"))
{
$stmt_test->execute();
$stmt_test->close();
}
else echo("Statement failed: ". $stmt_test->error . "<br>");
But, is the return value of the prepare statement only detecting if there is an error in the preperation of the SQL statement and not detecting execution errors? If so should I therefore change my execute line to flag errors as well like this:
if($stmt_test->execute()) $errorflag=true;
And then just to be safe should I also do the following after the statement has executed:
if($stmt_test->errno) {$errorflag=true;}
...Or was I OK to start with and the return value on the MySQLi prepare' statement captures all errors associated with the complete execution of the query it defines?
Thanks
C
Each method of mysqli can fail. Luckily, nowadays mysqli can report every problem to you, all you need is ask. Simply add this single line to the connection code,
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
And after that every error will reveal itself. No need to test any return values ever, just write your statements right away:
$stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)");
$stmt->bind_param('iii', $x, $y, $z);
$stmt->execute();
When the error occurs at any step, it will throw a usual PHP Exception that can be handled or just reported the same way as any other PHP error. Just make sure you configured PHP error reporting properly, i.e. on the dev server errors are displayed on-screen and on the production server errors are never displayed but logged instead.
Completeness
You need to check both $mysqli and $statement. If they are false, you need to output $mysqli->error or $statement->error respectively.
Efficiency
For simple scripts that may terminate, I use simple one-liners that trigger a PHP error with the message. For a more complex application, an error warning system should be activated instead, for example by throwing an exception.
Usage example 1: Simple script
# This is in a simple command line script
$mysqli = new mysqli('localhost', 'buzUser', 'buzPassword');
$q = "UPDATE foo SET bar=1";
($statement = $mysqli->prepare($q)) or trigger_error($mysqli->error, E_USER_ERROR);
$statement->execute() or trigger_error($statement->error, E_USER_ERROR);
Usage example 2: Application
# This is part of an application
class FuzDatabaseException extends Exception {
}
class Foo {
public $mysqli;
public function __construct(mysqli $mysqli) {
$this->mysqli = $mysqli;
}
public function updateBar() {
$q = "UPDATE foo SET bar=1";
$statement = $this->mysqli->prepare($q);
if (!$statement) {
throw new FuzDatabaseException($mysqli->error);
}
if (!$statement->execute()) {
throw new FuzDatabaseException($statement->error);
}
}
}
$foo = new Foo(new mysqli('localhost','buzUser','buzPassword'));
try {
$foo->updateBar();
} catch (FuzDatabaseException $e)
$msg = $e->getMessage();
// Now send warning emails, write log
}
Not sure if this answers your question or not. Sorry if not
To get the error reported from the mysql database about your query you need to use your connection object as the focus.
so:
echo $mysqliDatabaseConnection->error
would echo the error being sent from mysql about your query.
Hope that helps

Codeigniter error log not including file name

I'm trying to log errors from my codeigniter web app and I think the messages that get written to file are getting truncated. I say this because whenever the error is displayed on screen I get the file name where the error occurred whereas when I check the error logs it only says,
Query error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 24
Is there a way to have the error log return the file location of the error?
No, currently there isn't a built-in way to do this in CodeIgniter.
What you can do is to extend the core CI_Log class, override its write_log() method and use debug_backtrace() to get the appropriate file name and prepend it to the message.
// application/core/MY_Log.php
class MY_Log extends CI_Log {
public function write_log($level, $msg)
{
foreach (debug_backtrace() as $call)
{
// Somehow find the appropriate call here ...
if ( ! (/* condition to ignore error-handling calls */))
{
break;
}
$msg = '['.$call['file'].'] '.$msg;
break;
}
return parent::write_log($level, $msg);
}
}

Create new database and tables on the fly

I was reading the post "Create new database and tables on the fly"
I tried to implement an updated version of the create schema function:
public static function createSchema($schemaName)
{
$dbName = "db_{$schemaName}";
return DB::getSchemaBuilder()
->getConnection()
->statement("CREATE DATABASE :schema", ['schema' => $dbName ]);
}
but I get the following error:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?' at line 1 (SQL: CREATE DATABASE :schema)
PDO does not allowed to bind params on a create database query. So i'm not sure how to create DB's on the fly as safely as possible. Can anyone show me the way, before i have to introduce a security flaw in our site.
You cannot use bindings with CREATE DATABASE and PDO, because in CREATE DATABASE foo, foo isn't a quoted identifier, it's a raw new database name. You'll need to do any sanity checking yourself rather than relying on parameter binding to protect you.
public static function createSchema($schemaName)
{
$dbName = "db_{$schemaName}";
$quotedDbName = preg_replace("/[^_a-zA-Z0-9]+/", "", $dbName);
return DB::statement("CREATE DATABASE $quotedDbName");
}
See this question for more details about CREATE DATABASE with PDO binding.
public static function createSchema($schemaName)
{
// We will use the `statement` method from the connection class so that
// we have access to parameter binding.
return DB::getConnection()->statement('CREATE DATABASE :schema', ['schema' => 'db_' . $schemaName]);
}
i believe you dont need schema builder here

How to call a model function insider another controller in cakephp

i have my controller function like this:
private function _send_refund_scores($userId,$scores,$orderId){
$this->loadModel('Score');
$rtn = $this->Score->refund_user_scores($userId,$scores,$orderId);
if(!empty($rtn)){
return true;
}else return false;
}
while in another model Score , I have model function refund_user_scores;
the error like this:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near
'refund_user_scores' at line 1
so,any idea?
I guess you have defined refund_user_scores() as a private function in model Score.
That is why you are getting this error.

Call member function on a non-object, although the object exists

i have a very weird thing going on here. I check in the AppController's beforeFilter() function, wether an id exists or not. It works when I open the url /project/user/1, but when I open /project/user/edit/1 it says that I use a function on a non-object. I already checked if I really do so, but I don't. I output the value with pr() and it shows me the object content.
Here is my beforeFilter() function:
$request = $this->request;
if (isset($request->params['id'])) {
$model = Inflector::singularize(ucfirst($request->params['controller']));
$cond = array('conditions' => array($model . '.id' => $request->params['id']));
pr($this->{$model});
exit;
if (!$this->{$model}->find('first', $cond)) {
$this->Session->setFlash(__('Invalid id.'), 'flash_notice');
$this->redirect(array(
'manager' => (bool)$request->params['manager'],
'controller' => 'tournaments',
'action' => 'index'
));
}
}
The output of $model, before the id condition gets executed, contains the object data and is absolutley correct. I don't see the problem :/
Can you help me?
Thanks.
Okay I got the error...
The code just simply doesn't work, when the URL you open has some other error for example a database connection error. It's hard for me to explain but when I removed the code above and opened my URL an error like this came:
Database Error
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You
have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near 'isAdmin'
at line 1
When I fixed that bug, the code above works fine.

Categories