Hello I got this problem where my mysqli_query does not return any results.
public static function Execute($query){
self::$connection->query($query);
}
This is the function that I use for queries.
And this is the query itself;
$runtime = DataBase::Execute("SELECT SUM(runtime) runtime FROM test_tabela where user_id={Session::GetKey['user_id']} ");
But when I try to echo that result I get blank page.
Does any one know what's the problem because i can't find one maybe because I'm to tiered. Thanks in advance.
In your method you are not returning the mysqli_result object that are possibly being returned by mysql_query. Just use return:
public static function Execute($query){
return self::$connection->query($query);
}
Also I hope you sanitize Session::GetKey['user_id'] as a session variable is generally considered user input which cannot be trusted like that.
The mysqli extension also provides parametrized queries which are much safer than simple string interpolation.
Related
So I have a function called "escape" that looks like this:
function escape($string){
$escaped_string = mysqli_real_escape_string($this->conn, $string);
return $escaped_string;
}
I before running a query I send a variable (originated from user input obviously) here so its escaped for security reasons.
Now I know its possible to use array_walk to apply an array of values to this function, but I just want to know if there is any reason why I shouldn't? I know it sounds like a daft question but it would be nice and easy to apply it to an array of user inputted values rather than each variable.
Normally if when making a function I will do it this way:
function whatever($user_input){
$user_input = $this->escape($user_input);
$this->query("SELECT dog from pets where owner = '$user_input'");
e.c.t.
}
But if I have a lot of user inputted data from a form for example id rather just pass an array into the function and use array_walk on the escape function to save myself the hassle. But again is there any particular reason (from a security point of view) why this is not a good idea?
YES, absolutely
The practice is the reincarnation of the infamous "magic quotes" feature, that once was a part of the language, but now thank goodness it is not.
Such an approach will do you no good but only a give a false feeling of security and spoil your data for no reason.
You must use prepared statements for all database interactions that involve PHP variables. This is the only 100% safe solution, and it makes the function in question obsolete.
Here I've got an example for the select query using prepared statements, https://phpdelusions.net/mysqli_examples/prepared_select
With a simple helper function it turns into much simpler and cleaner solution than that escaping-driven mess
The book I'm learning PHP from says that in order to prevent people using things like quotes to alter the query, you should use the real_escape_string function. The author then goes on to say that on some older systems, where magic quotes is enabled, using real_escape_string could end up double escaping some characters, so he creates this function:
<?php
function mysql_fix_string($conn, $string) {
if (get_magic_quotes_gpc()) $string = stripslashes($string);
return $conn->real_escape_string($string);
}
?>
Would it be okay to turn this into a method in an extended class of the mysqli class? (There isn't any real reason why I wanted to, other than that I wanted to pass in as few arguments as possible.)
If so, is this the right way to do it?
class mysqli_extended extends mysqli {
public function fix_string($string) {
if(get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
return $this->real_escape_string($string);
}
}
And is this a situation where a static method makes more sense? If so, how could it be rewritten as a static method, and if not, then why?
Since I just asked like a million questions, I'll put a summary of them here:
Is it okay to create a method for this purpose. (Are there any drawbacks to this?)
Is the above code the correct way to do so?
Should it be a static method?
How would you make it a static method?
Magic quotes has been deprecated as of php 5.3 and is removed in 5.4. I recommend learn php the right way
PDO::quote always seems to slap on two single quotes regardless of the type of value I pass it, or the parameter type I set.
e.g.,
$x = null;
echo $pdo->quote($x,PDO::PARAM_NULL); // ''
Thus I've extended the PDO class with my own function,
public function quote($value, $parameter_type=PDO::PARAM_STR) {
if(is_null($value)) return 'NULL';
elseif(is_bool($value)) return $value ? 'TRUE' : 'FALSE';
elseif(is_int($value)||is_float($value)) return $value;
return parent::quote($value, $parameter_type);
}
Have I missed any cases? Is there any harm in doing this?
Do the different parameter types ever do anything?
Per the documentation, the results of a call to quote() are dependent on the PDO driver, because different databases escape strings in different ways. So some drivers may require quotes in different places than others. But really, if you know you don't need quotes, then you shouldn't be calling quote().
As for your function, it depends on what you're trying to do. If you're trying to build a database-agnostic data access layer, then your function will break for some databases. This is because not all DBs have boolean types, e.g. there is no such value as TRUE in SQLite.
But really, it would be better to just use prepared statements and not touch quote() at all. Even the documentation for quote says so, after all.
Here is the edited script without errors. And the 2 fixes applied to it. To those who helped in part, thank you. To mentions that the code is unclear or messy is inconsequential. Given that most of the following is common structure in mysql queries. Even the example documentation for mysql followed this similar flow. Members who reply should negate from pointless internet banter. Its more worth your time, and my own to do so. Those who stayed on topic and assisted, I thank you.
For example:
$row = mysqli_fetch_row(mysqli_query($con, "SELECT test_table.points FROM test_table WHERE test_table.key = '" . $key . "'"));
if ($row[0] > 0){ // exists
Where $row will return a non-zero result if true. Otherwise 0 on false. There is little need to check mysqli_fetch_row and/or mysqli_query. Since checking $row in simplicity works fine. It is unneeded to check mysqli_fetch_row and/or mysqli_query individually in a general exists condition. It does accurately provide exist / does not exist results. There is no $result $row $query just $row.
The noted deviation to that normal flow was my desire to use call_user_func. And to poll in func and params through $_GET. Will be looking more at PDO. However, the clean code before exec should do alright job for now. Which is to clean before exec.
All in all, the code works just as it should. And have since written more to manage a mysql database. From write, write chunk, read, read chunk, delete, delete chunk.
Also to collect numbered records on request. For example say you have 6 records for the same John Smith. You can now collate and scan for differences in those records. Either for what you want, dont want, etc. Or if say you just want to blindly call the first 3 of those records for John Smith.
mysqli_fetch_row & mysqli_fetch_row fix :
FROM Calling $con outside function then into as per mysql. Which in mysqli does not work as expected. There was no error with the functions, over how $con was being handled.
TO Calling $con inside function with just the added global $con. May end up using $GLOBALS even for this.
Result : Calling $con outside function then in works fine in mysql. In mysqli it requires global be set within the function. ie global $con. Or it fails.
call_user_func non-critical error fix :
FROM call_user_func($func($_GET['user'],$_GET['key'],$_GET['points'],$_GET['type']));
TO call_user_func($func,$_GET['user'],$_GET['key'],$_GET['points'],$_GET['type']);
Result : Both lines execute correctly. From executed with a non-critical error. TO does the same thing, but with no following non-critical error.
Sample Output for both : user=MY_Name;key=34342$ee56i1;points=1234;type=
-- code removed as fixes solved the issues --
You are using call_user_func wrong read the manutal
call_user_func first parameter is the callback - in your case it's a function inside your class so it should be something like this:
If you have a non-static function in an object:
class Test{
public function doit($a){
echo($a);
}
}
$t = new Test();
call_user_func(array($t,'doit'),'asfaasfs');
and in static functions inside object:
class Test{
public static function doit($a){
echo($a);
}
}
call_user_func('Test::doit','asfaasfs');
You have a few problems.
$con is declared outside the class, and is thus not available inside the class. You need to pass it into the class (the better option), or specify it as a global (the quick+dirty option).
mysqli_fetch_row(mysqli_query($con,'...'))
This code is obviously converted directly from your old mysql_xx() code, but it's not great.
You're ignoring any possible error condition that is returned by mysqli_query(). This means that if it fails, it'll pass false into the mysqli_fetch_row() function, which will then fail with a meaningless error expects parameter 1 to be mysqli_result, rather than actually telling you what the error was in the query.
The thing is, because of my first point above, with $con not being set, mysqli_query() is failing, and this is why you're getting the error in mysqli_fetch_row().
Ideally, you should split this code out into multiple lines. Call mysqli_query() on its own, then do some error checking, then call mysqli_fetch_row() only once you know that the query actually worked.
Hope that helps explain what the problems are here. Solve those two points, and you should be well on the way to sorting the whole thing out.
Once you've got rid of those fatal errors, you should also take time to work on the problem that your code is vulnerable to SQL injection attacks. You're currently passing your $_GET variables directly into the query strings without any sanitisation. This will make your system very fragile and easy to hack. You should consider using Parameterised Queries, which is a feature of the mysqli library designed to make it easier to deal with variables in SQL queries in a safe and secure way.
Your class is pointless at the moment, perhaps stick to writing imperative style code as it will at least be cleaner.
At the moment, you should pass $con to your MYsql class to use itself as a resource, not try to access it as a global variable.
Your are not filtering your user's input either, this is dangerous and could lead to SQL injection attacks on your site.
I'd encourage you to read through these two articles, and once you grok them, I'd also encourage you to simply switch to using PDO with prepared statements. This will stop SQL injection attacks that your code currently allows.
http://net.tutsplus.com/tutorials/php/pdo-vs-mysqli-which-should-you-use/
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
What is the difference between mysqli::query and mysqli::real_query?
OR
What is the difference between mysqli_query and mysqli_real_query?
mysqli::query will return a result if there is any.
mysql::real_query will return true on success or false if not
You could have seen this in the php doc:
query,
real_query.
Look at the documentation of mysqli_query():
Functionally, using this function is identical to calling
mysqli_real_query() followed either by mysqli_use_result() or
mysqli_store_result().
From what I understand real_query actually executes the query, and use/store_result initiates the process of retrieving a result set for the query.
query() does both.
Bit late, but the biggest advance for me is the RAM usage when these functions are called with default settings: with mysqli_real_query() you do not copy the whole result into the RAM, which mysqli_query() by default does (although it can be changed by using the $resultmode parameter).
In practice there is another difference I don't see in other answers. You could need to use mysqli_real_query() for a CALL statement.
If you are calling a stored procedure, then it can return more than one result. mysqli_query() will fetch the first result, but could be more results that needs to be fetched, and that would cause an error. You need to use mysqli_real_query(or mysqli_multi_query()) to fetch those result sets.
Sadly that explanation is in the stored procedures section of the PHP docs, so is hard to reach.
I let you a code example, just in case, calling a procedure that suppose to return several result sets using mysqli::real_query:
$query="CALL storedProcedure()";
if($conn->real_query($query)){
do{
if($result=$conn->store_result()) {
while($row=$result->fetch_assoc()) {
print_r($row);
}
$result->free();
}
}while($conn->more_results() && $conn->next_result());
}