Order results by category - php

I'm trying to order my blog posts by user defined category, i.e, the one they click on my blog page.
Here's my code thus far,
##########################################################
$cat = mysql_real_escape_string($_GET['category']);
##########################################################
$sql = "SELECT * FROM php_blog WHERE category = $cat ORDER BY timestamp";
$result = mysql_query($sql) or print ("Can't select entry from table php_blog.<br />" . $sql . "<br />" . mysql_error());
But that gives me this error,
Can't select entry from table
php_blog. SELECT * FROM php_blog WHERE
category = Update ORDER BY timestamp
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 'Update ORDER
BY timestamp' at line 1 Warning:
mysql_fetch_array(): supplied argument
is not a valid MySQL result resource
in
/home/funding9/public_html/jbblog/htdocs/category.php
on line 91

$sql = "SELECT * FROM php_blog WHERE category = '" . mysql_real_escape_string($cat) . "' ORDER BY timestamp";
The string needed to be quoted (in your example it was Update, needs to be 'Update'), and also I ran it through mysql_real_escape_string() to protect you from SQL Injection.

MySQL uses back ticks to allow you to escape names. You should be using something like the following:
$cat = mysql_real_escape_string($_GET['category'], $mysql_link);
$queryString = "SELECT * FROM `php_blog` WHERE `category` = '$cat' ORDER BY `timestamp`";
Supplying the link will make sure it is escaped for that connection, where different databases may have different configurations and require different things to be escaped in them.
You may also want to look into the use of prepared statements with MySQLi as well. That takes the difficulty out of knowing which input needs to be escaped, how it should be quoted and even some of the verification.

Related

I cannot figure out why I am getting this MySQL syntax error (PHP PDO) (MySQL)

I am trying to do a simple insert into my MySQL database, but I get this syntax error:
Fatal error: Uncaught PDOException: 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
'Combined Authority - ICT Service Desk Technician (WYCA 53) ' at line 2
Why?
Query:
$conn->exec("INSERT INTO jobs (jobname, category, contract, link)
SELECT * FROM (" . $name[$i] . "," . $category[$i] . "," . $contract[$i]
. "," . $link[$i] . ") AS tmp
WHERE NOT EXISTS (
SELECT link FROM jobs WHERE link = '" . " " . $link[$i] . ") LIMIT 1;");
$sql printed:
INSERT INTO jobs (jobname, category, contract, link) SELECT * FROM ( West
Yorkshire Combined Authority - ICT Service Desk Technician (WYCA 53)
Details ,' Other ',' Other
','https://bradford.engageats.co.uk/ViewVacancyV2.aspx?
enc=mEgrBL4XQK0+ld8aNkwYmF3VpPuSfX9mpz94c96U/BBgu1IZbwnQ0d+smFL6YrlPhdWkSGi559WmVou+xCXKsYHbHKP0EyHRCwf+vYTu8aYRJbtJgz78Wm2KQgu+LktushGT2Rg0PHjiRMA2Xyn4gw==') AS tmp WHERE NOT EXISTS ( SELECT link FROM jobs WHERE link ='https://bradford.engageats.co.uk/ViewVacancyV2.aspx?enc=mEgrBL4XQK0+ld8aNkwYmF3VpPuSfX9mpz94c96U/BBgu1IZbwnQ0d+smFL6YrlPhdWkSGi559WmVou+xCXKsYHbHKP0EyHRCwf+vYTu8aYRJbtJgz78Wm2KQgu+LktushGT2Rg0PHjiRMA2Xyn4gw==') LIMIT 1;
Apologies for the poor formatting above. Please copy and paste it into a text editor to view it better.
EDIT:
Strangely, this query works with dummy values, but it's still not working for arrays
INSERT INTO jobs (jobname, category, contract, link)
SELECT * FROM (SELECT 'Test', 'Test2',
'Test3','https://bradford.engageats.co.uk/ViewVacancyV2.aspx?
enc=mEgrBL4XQK0+ld8aNkwYmEUlxXraCLcDtY5P6rS92ks+pMDnlWa9QO6M/Df/HLticzgbgVWV
YayJj+zNDXalJnejkDY/4/gH0pIF9KyvMFXjn0u0quGSUzf4M/Gh0wF0MqIRgwLERFf+xXj6lw4s
tQ==') AS tmp
WHERE NOT EXISTS (
SELECT link FROM jobs WHERE link = 'https://bradford.engageats.co.uk/ViewVacancyV2.aspx?enc=mEgrBL4XQK0+ld8aNkwYmEUlxXraCLcDtY5P6rS92ks+pMDnlWa9QO6M/Df/HLticzgbgVWVYayJj+zNDXalJnejkDY/4/gH0pIF9KyvMFXjn0u0quGSUzf4M/Gh0wF0MqIRgwLERFf+xXj6lw4stQ=='
) LIMIT 1;
try this select query and do same with other variables :
SELECT * FROM ("'".$name[$i]."','".$category[$i]."', '".$contract[$i] ."', '". $link[$i] ."'") AS tmp
I can spot three different problems:
First of all, you are inventing your own SQL syntax and the server is not amused. You cannot SELECT * FROM (anything you want). You can only select from tables, views or subqueries.
Secondly, when you type e.g. foo in SQL the database engine needs a way to figure out if you mean a table or column or you mean literal word. The method used is single quotes:
SELECT foo AS this_is_a_column, 'foo' AS this_is_a_value
FROM bar
You can find more details at What is the difference between an identifier and a literal?
Last but not least, your overall use of the PDO extension is wrong. PDO provides a way to separate code and data but you are not using it. Rather than this:
$conn->exec("SELECT link FROM jobs WHERE link = '" . " " . $link[$i] . ") LIMIT 1;");
... you should be doing something like this:
$stmt = $conn->prepared("SELECT link FROM jobs WHERE link=? LIMIT 1");
$stmt->execute($stmt, array($link[$i]));
Use Quotes for string litterals
backticks for columns and tables names.
For more reference Check: http://php.net/manual/en/pdo.errorinfo.php

PHP: While loop not working after adjusting SELECT for SQL injection prevention

I am trying to set up PHP queries for MySQL in a way to prevent SQL injection (standard website).
I had a couple of INSERT queries where changing this worked well but on the following SELECT I keep getting an error since the update and it looks like the while loop doesn't work with the changes I made (it works well without using the statement as in the old code).
Can someone tell me what I am doing wrong here ?
New PHP:
$stmt = $conn->prepare("SELECT ? FROM TranslationsMain WHERE location LIKE '%calendar weekday%' ORDER BY sortOrder, ?");
$stmt->bind_param('s', $selectedLang);
$stmt->execute();
$result = $stmt->get_result();
while($arrCalWeekdays = $result->fetch_assoc()){
$calWeekdays[] = $arrCalWeekdays;
}
$conn->close();
Old PHP (changed part):
$sql = "SELECT " . $selectedLang . " FROM TranslationsMain WHERE location LIKE '%calendar weekday%' ORDER BY sortOrder, " . $selectedLang;
$result = $conn->query($sql);
while($arrCalWeekdays = $result->fetch_assoc()){
$calWeekdays[] = $arrCalWeekdays;
}
$conn->close();
Error message:
Fatal error: Call to a member function fetch_assoc() on a non-object in /homepages/21/d580042014/htdocs/myform.php on line 21
Many thanks in advance.
You cannot bind column and table names, only data. You need to specify the table and then bind for your '%calendar weekday%'.
$stmt = $conn->prepare("SELECT " . $selectLang . " FROM `TranslationsMain` WHERE `location` LIKE ? ORDER BY `sortOrder`, " . $selectedLang);
$stmt->bind_param('s', $calendar_weekday);
If you want to use dynamic table / column names you should perform the minimal white-listing of those items. You can build a dynamic white list by asking the database what columns are valid for a given database table. For example:
SELECT `COLUMN_NAME`
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA` = `database_name`
AND `TABLE_NAME` = `table_name`
You could place all of this information in arrays and then check to make sure the table / column names used in the query are in the arrays. Extra consideration for table and column names should be performed, making sure that no key / reserved words are used for these names.
Finally, use backticks around the validated table / column names when calling the values for the dynamic queries. This will cover any potential changes to the key / reserved words list and provides an additional layer of protection.

check the manual that corresponds to your MySQL server version

can't figure out what's the problem with this code
keep getting error on
Notice: Undefined index: userID in C:\wamp\www\myProject\editProfile\edit_save.php on line 10
and
Could not run query: 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 '(UserID, matrix_num,student ,username ,town ,email , txtFavorite,noDate,txtMobil' at line 1
if($_GET) {
$noEdit = $_POST[''];
//"SELECT *FROM "
$sql = "SELECT * FROM tblmyprofile where student='$name', username='$username', matrix_num='$matric', town='$town' and mail='$email'";
$query = mysql_query($sql, $masuk,$boleh) or die ("Gagal query".mysql_error());
$data = mysql_fetch_array($query);
}
The comma operator is invalid in the WHERE clause.
It looks like you wanted logical AND or OR operators. A query of the form something like this:
SELECT t.*
FROM tblmyprofile t
WHERE t.student = 'fee'
AND t.username = 'fi'
AND t.matrix_num = 'fo'
AND t.town = 'fum'
AND t.mail = 'foo'
But that's a very odd construct for a SQL query; there's nothing invalid with it. But usually, with SELECT, we're usually intending to retrieve rows based on a few predicates, and then getting the values from the row back.
For debugging issues with SQL queries, it's often a good idea to string together the SQL text you intend to send to the database, and then echo (or printf or vardump) the string, e.g.
$sql = "SELECT col, expr, col FROM mytable WHERE col = 'abc'";
echo $sql;
Then, reference $sql in the call to parse and execute a SQL statement.
I believe part of the issue you are encountering may be the construction of the string containing the SQL text. Some languages are persnickety about including variables and quotes within string literals.
e.g.
$sql = " WHERE t.fee = '" . mysql_real_escape_string($foo) . "'"
. " AND t.fi = '" . mysql_real_escape_string($bar) . "'"
. ... ;
Again, after you put together the SQL text, echo it out for debugging, and verify that it's the string you intend to send to the database.
Also note that the mysql_ interface is deprecated. New development should be using mysqli_ or PDO. Also note that including any unsafe variables in SQL text can lead to SQL injection vulnerabilities. Either "escape" special characters in variables you include in the SQL text, or better, use prepared statements with bind parameters, to avoid SQL injection.

PHP MySQL - selecting values from table 1 which are not in table 2

This may be simple to solve but I'm having trouble with this piece of code - I'm a self taught newbie with PHP, and the code I've come up with doesn't seem to want to work.
The pages are for an online entry system for a sports competition. Judges' details are stored in table "club_judges", and users can enter them into a competition by copying them into "competition_judges". This is done via a checkbox form in a table.
I want to add functionality whereby judges who are already added to the competition do not appear in the import form, however my code does not seem to work. I am using a unique field of "bg_number" (the sport's identification number) to search for an existing entry.
Current code:
$existing_judges = mysql_query("SELECT bg_number FROM competition_judges WHERE competition='Test Competition'");
$existing_judges_fetch = mysql_fetch_array($existing_judges);
$existing_judges_array = "('" . implode( "', '", $existing_judges_fetch ) . "');" ;
$query = "SELECT * FROM club_judges WHERE (`club`='Test Club') AND (`bg_number` NOT IN '$existing_judges_array') ORDER BY name ";
$result = mysql_query($query) or die(mysql_error());
Error displayed:
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 ''('1234567', '1234567');') ORDER BY name' at line 1
For reference 1234567 is the bg_number for my test judge.
Any help would be greatly appreciated!
why dont u use just one query
SELECT *
FROM club_judges
WHERE `club`='Test Club'
AND `bg_number`
NOT IN (SELECT bg_number FROM competition_judges WHERE competition='Test Competition')
ORDER BY name
Use can use a single query instead like this:
$query = "SELECT * FROM `club_judges` WHERE `club`='Test Club'
AND
`bg_number` NOT IN
(SELECT `bg_number` FROM `competition_judges` WHERE `competition`='Test Competition')
ORDER BY `name` ";
$existing_judges_fetch = mysql_fetch_array($existing_judges);
$result = mysql_query($query) or die(mysql_error());
here's a JOIN version
SELECT a.*
FROM club_judges a
LEFT JOIN competition_judges b
ON a.bg_number = b.bg_number AND
b.competition='Test Competition'
WHERE b.bg_number IS NULL AND
a.club = 'Test Club'
ORDER BY a.name
To fully gain knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins

MySQL Update Fix Two rows with one query

This is the code giving me issue - I'm trying to update multiple records with one insert. The values are put in an array and using a foreach I've prepared the mysqli update. But it's not working. Just gives a MySqli error about the syntax on the update.
foreach($users as $user){
if(empty($course)) continue;
$query_string .= " SET group_id='$group_id' WHERE user_id='".$user."'; ";
}
$query_string = substr($query_string,0,-1);
$query = "UPDATE users" . $query_string;
$result = mysqli_query($dbc, $query) or trigger_error("Query: $query");
The error it gives is:
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 'SET group_id='10' WHERE user_id='5''. I think it's the ';' in the middle that mysqli isn't accepting.
Assuming you've got more than one user, your query will look like
UPDATE users SET ... SET ... SET ... SET ...
which is incorrect. You cannot do updates to multiple rows in this fashion. Either do multiple queries, each updating one student, or you'll have to build a huge case/if block to do this in a single query.
You'd be better off doing the multiple queries, as you'll probably spend more time BUILDING the monolithic query than it'd take to run the individual updates.
How about WHERE...IN
UPDATE foo SET bar = 0 WHERE baz IN (1,2,3,4,5,6)
(presuming that you are setting them all to the same group ID, which is not clear in the context provided)
try this code:
<?php
$queries = array();
foreach($users as $user){
if(empty($course)) continue;
$queries[] = "update users set group_id = '" . mysql_real_escape_string($group_id) . "' where user_id = '" . mysql_real_escape_string($user) . "'";
}
array_map('mysql_query', $queries);
?>
Your problem is that you don't separate the different users with ;. Since you're updating all users to have the same group (I'm not sure this is the case, otherwise it will get much more complex) you can simply expand the criteria with OR. Your resulting query would look something like the following:
UPDATE users SET group_id='42' WHERE user_id='1' OR user_id='2' OR user_id='3';
Another solution would be to use WHERE ... IN. Here's an example of that:
UPDATE users SET group_id='42' WHERE user_id IN (1, 2, 3);

Categories