I'm trying to get simple info from a database and echo it to screen, but it's not working for me.
$con=mysqli_connect("SERVER.COM","USERNAME","PASSWORD", "DATABASE");
function GetTeamFixtures($team)
{
$queryget = mysqli_query($con, "SELECT * FROM 'mlsfixtures' WHERE team='$team' LIMIT 1");
$row = mysqli_fetch_assoc($queryget);
$gw1 = $row['gw1'];
$gw2 = $row['gw2'];
echo $team.' '.$gw1.' '.$gw2.'<br>';
}
$team = "Chicago Fire"; GetTeamFixtures($team);
$team = "Chivas USA"; GetTeamFixtures($team);
$team = "Colorado Rapids"; GetTeamFixtures($team);
//continue for all teams - removed for simplicity
Here are the error messages I get (line 46 is the $queryget= one and line 49 is the $row = one).
Warning: mysqli_query() expects parameter 1 to be mysqli, null given in server.com\teamfix.php on line 46
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, null given in server.com\teamfix.php on line 49
Any idea why? I'm not sure if there's an easier way of doing the same thing but for 19 different teams.
One of the errors i've found, aside from the two users that explained about connection, is the invalid use of single quotes.
Tables names should not be wrap with single quotes as they are identifiers and not a string literals. Remove the single quotes and it should work,
SELECT * FROM mlsfixtures WHERE team='$team' LIMIT 1
MySQL - when to use single quotes, double quotes, and backticks?
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
Another way to access variables outside a function instead of using global variables is to add it up in its parameters
E.g
function GetTeamFixtures($team,$con)
{
// query inside
}
Also as J W says in your query remove '' or replace it with `` backticks..
(This is my attempt at combining all the other answers in a concise manner.)
There are two problems.
First, the global variable $con is not accessible from within your function without a global statement. The global statement can be used to create a reference to $con from within your function.
global $con; // is equivalent to:
$con =& $GLOBALS['con'];
Second, the table name cannot be enclosed in single quotes. Remove the quotes.
// By the way, this should be using mysqli::prepare and mysqli_stmt::bind_param
// to prevent SQL injection
$queryget = mysqli_query($con, "SELECT * FROM mlsfixtures WHERE team='$team' LIMIT 1");
You don't have access to $con from within your function. This should work:
$con = mysqli_connect("SERVER.COM","USERNAME","PASSWORD", "DATABASE");
function GetTeamFixtures($team)
{
global $con;
$queryget = mysqli_query($con, "SELECT * FROM `mlsfixtures` WHERE `team`='$team' LIMIT 1");
$row = mysqli_fetch_assoc($queryget);
$gw1 = $row['gw1'];
$gw2 = $row['gw2'];
echo $team.' '.$gw1.' '.$gw2.'<br>';
}
P.S. If the $team you're passing in to GetTeamFixtures comes from user input, you should prepare your statement, to prevent SQL injection.
$con isn't visible within the function. If you want a global variable to be in scope in a function, you must declare it global:
function GetTeamFixtures($team) {
global $con;
# ...
}
Related
This question already has answers here:
Use an array in a mysqli prepared statement: `WHERE .. IN(..)` query [duplicate]
(8 answers)
Closed 11 months ago.
I'm trying to create a select query with dynamic where clause and dynamic parameters but I always get error :
Warning: mysqli_stmt::bind_param(): Number of elements in type
definition string doesn't match number of bind variables
Which I sincerely do not understand since it seems the count is alright. So this is what the code really looks like in its rude format. I can't see what I'm doing wrong.
//get variables
$mediaArray ='Facebook,Twitter,Twitch,';
$otherMedia = 'House';
//convert string to array
$socialArray = explode(',', $mediaArray)
//declare some variables to be used later
$andwhere = '';
$bp = '';
$socialmarray = ''
//get every value from array of social media
foreach($socialArray as $socialmedia){
$socialmarray .=$socialmedia.',';
$andwhere .= " AND socialmedianame=?";
$bp .='s';
}
//test strings
echo $wheres = $andwhere;//AND socialmedianame=? AND socialmedianame=? AND socialmedianame=?
echo $bip = $bp.'s';//ssss
echo $validarayy = rtrim($socialmarray,',');//Facebook,Twitter,Twitch
//select query
$selectquery = $conn->prepare("select * from mediaservices where socialmedianame=? $wheres");
$selectquery->bind_param("$bip",$otherMedia,$validarayy);
$selectquery->execute();
$resultquery = $selectquery->get_result();
Because:
You are using user-supplied data, you must assume that your query is vulnerable to a malicious injection attack and
the amount of data that is to be built into the query is variable/indefinite and
you are only writing conditional checks on a single table column
You should use a prepared statement and merge all of the WHERE clause logic into a single IN statement.
Building this dynamic prepared statement is more convoluted (in terms of syntax) than using pdo, but it doesn't mean that you need to abandon mysqli simply because of this task.
$mediaArray ='Facebook,Twitter,Twitch,';
$otherMedia = 'House';
$media = array_unique(explode(',', $mediaArray . $otherMedia));
$count = count($media);
$conn = new mysqli("localhost", "root", "", "myDB");
$sql = "SELECT * FROM mediaservices";
if ($count) {
$stmt = $conn->prepare("$sql WHERE socialmedianame IN (" . implode(',', array_fill(0, $count, '?')) . ")");
$stmt->bind_param(str_repeat('s', $count), ...$media);
$stmt->execute();
$result = $stmt->get_result();
} else {
$result = $conn->query($sql);
}
foreach ($result as $row) {
// access values like $row['socialmedianame']
}
For anyone looking for similar dynamic querying techniques:
SELECT with dynamic number of LIKE conditions
INSERT dynamic number of rows with one execute() call
In your query:
$selectquery = $conn->prepare("select * from mediaservices where socialmedianame=? $wheres");
The ? represents one parameter to pass in, and the evaluation of $wheres adds another three, giving you four total parameters.
bind_param() should take a string representing the types of the variables to insert as the first parameter, and the variables themselves as the subsequent parameters.
In your bind:
$selectquery->bind_param("$bip",$otherMedia,$validarayy);
$bip evaluates to ssss and $otherMedia is a single string ("House"). You might expect $validarayy to be three strings, but rtrim() returns a string. Thus, it is only one string ("Facebook,Twitter,Twitch"). You pass through two variables when the query is expecting four:
$conn->prepare("select * from mediaservices where socialmedianame=House AND socialmedianame=Facebook,Twitter,Twitch AND socialmedianame=? AND socialmedianame=? AND socialmedianame=?"
To correct this, you'll want to convert $validarayy back to an array, and use the index for the various inputs:
$socialmarray2 = explode(',', $validarayy);
$selectquery->bind_param("$bip", $otherMedia, $socialmarray2[0], $socialmarray2[1], $socialmarray2[2]);
Also note that your sample code has a few missing semicolons; you'll need to fix these in order for your code to work correctly.
This can be seen working here.
Finally, note that even if you were to split the three strings out correctly, the selection of ... AND socialmedianame=Facebook AND socialmedianame=Twitter AND socialmedianame=Twitch will never match any results; socialmedianame can only contain one value. You're probably looking to substitute your AND statements with OR statements.
I'm beginning with PHP and i need your help.
I create a try to list all members who has the same interest that the current_member( i mean the connected member ).
I write this :
$current_members = params('current_member');
$members_all = option('db')->query('SELECT * FROM members WHERE interest = $current_members["interest"] ORDER BY lastname, firstname')->fetchAll();
set('members_all', $members_all);
When I go on my page I have the error :
Fatal error: Call to a member function fetchAll() on a non-object
And in my view I just write this :
<h2 id="member-<?= $member['id'] ?>">
<?= avatar_tag($member,'30x30') ?>
<?=$member['firstname']?><small> <?= $member['lastname'] ?></small>
</h2>
I dont understand this error, anyone can help me ?
Thank's for your help.
Do not chain calls to query() and fetchAll() like you are doing. That's bad practice. Never assume your query worked, always check to see if it did.
$db = option('db');
$query = $db->query('SELECT ...');
if($query === FALSE){
print_r($db->errorInfo());
die;
}
$members_all = $query->fetchAll();
(Since you are calling fetchAll(), I assume you are using PDO (and not MySQLi))
Also, do not try to concatenate variables into your SQL query. (P.S. You're not even doing that, you are using single quotes, so $current_members["interest"] is not being read as a variable) That's just asking for an SQL injection attack. What you want to do is use prepared statements.
$db = option('db');
$query = $db->prepare('SELECT * FROM members WHERE interest = ? ORDER BY lastname, firstname');
$exec = $query->execute(array($current_members['interest']));
if($exec === FALSE){
print_r($query->errorInfo());
die;
}
$members_all = $query->fetchAll();
The "call to a member function on a non-object" error, means that you are trying to call a method on a variable that does not represent an object.
You have the following methods called one after the other on the $members_all denifition:
option('db')->query("...")->fetchAll();
You call the method "query" of whatever returns option('db') with some SQL query, and then you call fetchAll() method to whatever returns that "query" method.
I do not know if I explained myself well, the main point is that when you execute the query method it is returning something that has not the "fetchAll" method, in your case your SQL is wrong and probably query() is returning NULL or FALSE instead of a result set.
Change your single quotes with double quotes or concatenate the $current_member['interest'] variable.
IN your sql query
'SELECT * FROM members WHERE interest = $current_members["interest"] ORDER BY lastname, firstname'
you are using single quotes, so $current_members["interest"] actually does not resolve to a PHP variable, it is a string. You can switch single and double quotes:
Made an edit here, passing array offset was not fortunate:
$interest = $current_members['interest'];
"SELECT * FROM members WHERE interest = $interest ORDER BY lastname, firstname"
Unfortunately you did not share any of the underlying database code, but assuming option('db') is a pdo object, this should work fine.
If option('db') really is a pdo, before executing any statement add:
option('db') -> setAttribute( \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION );
this will tell you the exact error
I am a php beginner.
I have the following script which works if I do not use _GET['version'] in the query, but works if I remove it. There is no error; I am not sure why it is not working.
<?php
// Specify your table name
$hostname = 'localhost';
$dbname = 'stats';
$table_name = 'st_stats';
$username = 'test';
$password = 'test';
try
{
$conn = new PDO("mysql:host=$hostname;dbname=$dbname",$username,$password);
//By default mode is silent and exception is not thrown. So I it to throw ex
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// If the query is like this no error is given but page shows up blank
$stmt = $conn->query("SELECT * FROM $table_name where version = $_GET['version']", PDO::FETCH_ASSOC);
// This works if uncomment below line instead and comment line above
//$stmt = $conn->query("SELECT * FROM $table_name", PDO::FETCH_ASSOC);
$count = $stmt->rowCount();
echo("<h1>currently $count records</h1>");
}
catch(PDOException $e)
{
echo 'ERROR: ' . $e->getMessage();
}
?>
I want to access the page like this
http://www.mydomain/records.php?version=1.2
Note that version column does exit in the table
You could try to avoid a bit of sql injection here by preparing the statement properly:
$v_term = $_GET['version'];
$query = "SELECT * FROM $table_name where version = :term";
$result = $conn->prepare($query);
$result->bindValue(":term",$v_term);
$result->execute();
Also, run the statement straight from the db if you can to make sure you are getting records back. Other than that, there is no other way to debug this for you from what you given us.
Maybe version is not an integer therefore need quotes ?
"SELECT * FROM $table_name where verion = '".$_GET['version']."'",
Anyway you are vulnerable to sql injection and also misusing PDO
You should at least bindParam/bindValue
Or use execute() and past the $_GET value
As documented under Variable parsing:
There are two types of syntax: a simple one and a complex one.
[ deletia ]
Example #8 Simple syntax example
[ deletia ]
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;
[ deletia ]
Complex (curly) syntax
This isn't called complex because the syntax is complex, but because it allows for the use of complex expressions.
[ deletia ]
// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}";
That is, you can reference associative arrays from within a double-quoted string in one of two ways:
// simple - don't quote your keys
"... $_GET[version] ..."
// complex - you may quote your keys, but must surround the expression in braces
"... {$_GET['version']} ..."
HOWEVER, you shouldn't be doing either here. You should instead be using a parameterised statement in order to prevent SQL injection attacks:
$stmt = $conn->prepare("SELECT * FROM $table_name WHERE verion = ?");
$stmt->execute([$_GET['version']]);
This doesnt work because you're trying to access $_GET['version'] an array variable within a string here
"SELECT * FROM $table_name where version = $_GET['version']", PDO::FETCH_ASSOC
placing {} around the variable will fix this one issue
$stmt = $conn->query("SELECT * FROM $table_name where verion = {$_GET['version']}", PDO::FETCH_ASSOC);
But you should also sanitize this value before you put it right int a sql statement
You have verion rather than version in your query. You're also not passing the value of $_GET['version'], you're passing the string "$_GET['version']" right into the query. Update your query to this:
$stmt = $conn->query("SELECT * FROM $table_name where version = {$_GET['version']}", PDO::FETCH_ASSOC);
Wrapping a variable that's inside a double quoted string ("") in curly braces ({}) evaluates to the value of the variable.
If you do this you will be wide open to SQL injection attacks. Be sure to sanitize the variable before you run the query, or better yet consider prepared statements.
The following code I used for a image thumbnail when clicked it gets executed by taking the it "ID " from the database.
echo '<a class="thumbnail" href="view.php?id='.$row['id'] .'"">';
The code below actuality handle the GET variable passed through the above code.
<?php
require '../header.php';
if (isset($_GET['id']))
{
require '../../functions/function_db.php';
$id =mysql_real_escape_string (htmlentities($_GET['id']));
$sql = "SELECT * FROM `site_products` WHERE `id` = $id LIMIT 1";
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result))
{
$product_name = $row['product_name'];
$price = $row['final_price'];
$desc = $row['short_description'];
}
}
?>
In spite of using mysql_real_escape_string the URL becomes SQL injection vulnerable in following scenario .
http://localhost/cart/pages/men/view.php?id=1'
http://localhost/cart/pages/men/view.php?id=1 orderby 1
and the webpage gives following mysql error.
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given
How to solve this ???
Updated because off an comment from Jason McCreary
prepared statements are more safe but always force an type when you bind the values.
But you still need to watch out for second order SQL injections they are still possible then even if you make use off prepared statements
Id should be an integer just cast it to an int and filter out NULL bytes, NULL bytes are also evil things
$id = (int)(str_replace("\0", "", $_GET['id']));
$id =mysql_real_escape_string (htmlentities($_GET['id']));
$sql = "SELECT * FROM `site_products` WHERE `id` = $id LIMIT 1";
This is a common misuse of mysql_real_escape_string(). The function is only for escaping single quoted strings for MySQL queries. Single quotes (apostrophes) should always go around the return value. And why htmlentities() here?
Cast the value to an integer instead (e.g. $id = (int)$_GET['id'];, having the effect of keeping only digits 0-9), or put single quotes around the escaped value, or better yet, switch to mysqli or PDO prepared statements.
See also: How can I prevent SQL injection in PHP?
I am writing my PHP blog engine. I am using PDO for it. And now, when I am writing class Member - I have an error.
Fatal error: Call to a member function fetch() on a non-object in
/home/tucnak/Server/scripts/php/classes/Member.php on line 42
And source code of my Class:
public function authMember($user, $password)
{
$password = hashIt($password);
$count = 100500;
$count = $this->db->query("SELECT count(*) FROM users-general WHERE nick = $user AND password = $password;")->fetch();
echo($count);
// if ($count == 1){ return 1; } else { throw new Exception("",491); }
}
I have an error using this function.
Your query probably fails because you don't have quotes wrapped around your query.
When that happens, query() will return false instead of an object, breaking the chain.
Don't do it this way; run the query first, save its result, then check whether it's false.
By the way, you should really use prepared statements - your current statement is vulnerable to SQL injection.
"SELECT count(*) FROM `users-general` WHERE nick = '$user' AND password = '$password'"
note the single quotes of 2 different types
Thought, your misunderstanding has nothing to do with PDO. it's basic SQL syntax you have to learn