I am learning MySQL/php through online tutorials and have found the techniques and syntax different from different sources.
In one tutorial, I enter data (from an HTML form) like this:
$table = "ENTRIES";
$sql = "INSERT INTO $table SET
TITLE = '$_POST[title]',
SUMMARY = '$_POST[summary]',
CONTENT = '$_POST[content]'";
$query = #mysql_query($sql);
And in another, like this:
mysql_query("
INSERT INTO `posts` SET
`title` = '{$_POST['title']}',
`contents` = '{$_POST['post']}'
");}
They both work, and I understand the different variable arrangements. BUT I have the following questions, probably all related. (I gather that #mysql_query suppresses error messages, SO if that is what is going on here, can you please explain how it is functioning and what is actually proper syntax?)
1) In the first example, in #mysql_query(), it doesn't matter if I use ("") or ('') ... but in the second example, in mysql_query(), it breaks if I use (''). In fact it tells me that there is an unexpected {, which leads to my next question:
2) What is the deal with the {} in the second example? They don't seem to be doing anything, but it breaks without them.
3) In the first example, is breaks if I enclose title, summary, and content in single quotes ''. In the second, with 'title' and 'post', it breaks if I don't!
Any explanations or references/links comprehensible to a beginner would be much appreciated!
Run far away from this tutorial and fine one that uses PDO / mysqli and explains how to properly parameterize queries.
Anyway, your questions are PHP specific and have to do with variable interpolation in strings. In quoted strings (") variables are interpolated, and arrays can be accessed via:
"{$var['value']}"
"$var[value]"
Either one is valid ... they function identically and it's up to personal preference which one you should use.
mysql_query takes a string as an argument, so it actually makes no difference how you build it. Both of the above are valid. Using # makes no difference -- in fact, you shouldn't use it, and you should properly handle possible errors and check mysql_error
Related
The MySQL documentation says that it should be \'. However, both scite and mysql shows that '' works. I saw that and it works. What should I do?
The MySQL documentation you cite actually says a little bit more than you mention. It also says,
A “'” inside a string quoted with “'” may be written as “''”.
(Also, you linked to the MySQL 5.0 version of Table 8.1. Special Character Escape Sequences, and the current version is 5.6 — but the current Table 8.1. Special Character Escape Sequences looks pretty similar.)
I think the Postgres note on the backslash_quote (string) parameter is informative:
This controls whether a quote mark can be represented by \' in a string literal. The preferred, SQL-standard way to represent a quote mark is by doubling it ('') but PostgreSQL has historically also accepted \'. However, use of \' creates security risks...
That says to me that using a doubled single-quote character is a better overall and long-term choice than using a backslash to escape the single-quote.
Now if you also want to add choice of language, choice of SQL database and its non-standard quirks, and choice of query framework to the equation, then you might end up with a different choice. You don't give much information about your constraints.
Standard SQL uses doubled-up quotes; MySQL has to accept that to be reasonably compliant.
'He said, "Don''t!"'
What I believe user2087510 meant was:
name = 'something'
name = name.replace("'", "\\'")
I have also used this with success.
There are three ways I am aware of. The first not being the prettiest and the second being the common way in most programming languages:
Use another single quote: 'I mustn''t sin!'
Use the escape character \ before the single quote': 'I mustn\'t sin!'
Use double quotes to enclose string instead of single quotes: "I mustn't sin!"
just write '' in place of ' i mean two times '
Here's an example:
SELECT * FROM pubs WHERE name LIKE "%John's%"
Just use double quotes to enclose the single quote.
If you insist in using single quotes (and the need to escape the character):
SELECT * FROM pubs WHERE name LIKE '%John\'s%'
Possibly off-topic, but maybe you came here looking for a way to sanitise text input from an HTML form, so that when a user inputs the apostrophe character, it doesn't throw an error when you try to write the text to an SQL-based table in a DB. There are a couple of ways to do this, and you might want to read about SQL injection too.
Here's an example of using prepared statements and bound parameters in PHP:
$input_str = "Here's a string with some apostrophes (')";
// sanitise it before writing to the DB (assumes PDO)
$sql = "INSERT INTO `table` (`note`) VALUES (:note)";
try {
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':note', $input_str, PDO::PARAM_STR);
$stmt->execute();
} catch (PDOException $e) {
return $dbh->errorInfo();
}
return "success";
In the special case where you may want to store your apostrophes using their HTML entity references, PHP has the htmlspecialchars() function which will convert them to '. As the comments indicate, this should not be used as a substitute for proper sanitisation, as per the example given.
Replace the string
value = value.replace(/'/g, "\\'");
where value is your string which is going to store in your Database.
Further,
NPM package for this, you can have look into it
https://www.npmjs.com/package/mysql-apostrophe
I think if you have any data point with apostrophe you can add one apostrophe before the apostrophe
eg. 'This is John's place'
Here MYSQL assumes two sentence 'This is John' 's place'
You can put 'This is John''s place'. I think it should work that way.
In PHP I like using mysqli_real_escape_string() which escapes special characters in a string for use in an SQL statement.
see https://www.php.net/manual/en/mysqli.real-escape-string.php
select name from movies where id = 1; gives me
name
----------
How the 'A' Stole Christmas
How would I select in order to get
name
----------
How the \'A\' Stole Christmas
I can use replace(title,'\'','\\\'') which turns ugly since I need to do it twice one for single & double quote, Curious to know if there is cleaner approach
Struggling with escaping characters is a sign that you may be unnecessarily converting strings manually as data flows through different systems. The question I would ask is whether it is necessary to have escaped strings for your requirements.
When constructing and executing your queries you should use bind variables which removes the need to quote strings to build up your Sql queries and minimizes the risk of Sql injection security issues.
See http://php.net/manual/en/mysqli-stmt.bind-param.php
Once you have Sql results in a variable or PHP structure it is often better to find functions/libraries such as JSON functions described at https://coderwall.com/p/p2kumg/json_encode-vs-serialize-with-php-arrays
And of course there's http://www.w3schools.com/php/func_string_addslashes.asp as mentioned by D4V1D as a comment.
Edit ...
There also appears to be a Mysql QUOTE() function that does what you are asking.
See http://www.w3resource.com/mysql/string-functions/mysql-quote-function.php
How to disable highlighting for SQL code in phpstorm ?
i ever disabled all sql inspection..but color and fonts rules continue to overight
my php string color rules .
Here is an Exemple for what i want to achieve :
$var_php = " all text here is red , SELECT * and whatever sql code is in red too " ;
SQL Language is automatically injected in strings that contain SQL code (which are detected by the typical patterns, e.g. select xx from etc). It also injected in HEREDOC/NOWDOC if you use special label (SQL).
You can disable these (selected on the screenshot below) and any other unwanted injection rules or create your own at Settings/Preferences | Editor | Language Injections.
P.S. Since you do not need any SQL/DB support at all, you may just disable SQL/database support plugins completely.
If you do like such injections in general but just do not want them in a specific place only (e.g. because of the false positive match) then you can force plain text in that string. For example:
$str = /** #lang Text */ 'Select all entries from my cool database';
Please note that such comment must be placed just before the actual string (so it can be used in function call params or alike), not before the whole variable assignment/statement like ordinary PHPDoc comments.
P.S. The same is possible other way around: force SQL in some string that is not autodetected by Language Injection rules (e.g. when string is split into concatenated bits or uses unknown/unexpected sequence/syntax).
You can disable it while leaving other SQL highlighting / inspections alone by creating a new IntelliLang injection which specifically does not match DQL. I used the presence of the : character. This will prevent the IDE from highlighting DQL, and also marking it as error or reformatting it incorrectly.
I've created a Gist with instructions here:
https://gist.github.com/willemnviljoen/d20ad8ad0cc365a7e80744328246610f
Usually PHPstorm does a pretty good job of deciding when SQL string literals should be inspected as SQL code. For individual cases where it gets it wrong, the most "proper" way to disable inspection for a single line is probably the PHPDoc comment mentioned in another answer, like:
$str = /** #lang Text */ 'Select the answer from the list';
But that seems messy to me. Luckily, you can trick PHPstorm pretty easily, as it seems to ignore the string if the first word in a "sentence" is not a SQL keyword (SELECT/UPDATE etc). So a simple (though a bit more hackish) way is to just split the string, like:
$str = 'Select'.' the answer from the list';
When I search any record by chapter number then it works.
But the problem is when I select chapter number 1 or 2 from drop-down and the search all records included in that chapter.
It displays all records included in 1,11,21,31...or 2,21,12,...like this.
I know I wrote 'like' there that's why it happens. But when i write " = " operator that I commented in my code that also didn't work for me.
What will be the perfect query to solve this problem?
My Code:
<?php
include("conn.php");
$name=$_POST['fname'];
$name2=$_POST['chapter'];
$sql="SELECT distinct * FROM $user WHERE question like '%".$name."%' and Chapter like '%".$name2."%'";
// $sql="SELECT * FROM $user WHERE question='$name' and Chapter='$name2'";
$result=mysql_query($sql,$connection) or die(mysql_error());
while($row=mysql_fetch_array($result)) {
?>
I would be interested to see what the type of 'Chapter' is in the returned query, and try to see why it is that the equality comparison doesn't work.
If the typing is straightforward (i.e. it really is just plain old strings), then I'd be looking for whitespace characters or something like that which is foiling the equality comparison.
Similarly, I'm wondering whether it's the equality on the 'Question' that is messing up your alternate query.
At a guess, try one of the following:
$sql="SELECT distinct * FROM $user WHERE question like '%".$name."%' and Chapter like '$name2'";
$sql="SELECT distinct * FROM $user WHERE question like '%".$name."%' and Chapter='$name2'";
Oh, and you should really do something about escaping those parameters properly to avoid any nasty SQL injection attacks.
The problem is this part of the first query:
Chapter like '%".$name2."%'
If = doesn't work, then I can think of two things. The first is that Chapter is really a list, probably a comma delimited list. The second is that there are extraneous characters in the database.
If Chapter is really a list, use find_in_set() instead:
find_in_set($name2, Chapter) > 0
You directly use $_POST variables in your SQL query which makes you vulnerable to SQL injection attacks. Please take a look at this page for ways around that: http://bobby-tables.com/php.html. You should use either mysql_real_escape_string or prepared statements (better). The best solution would probably be to use PDO.
Also if you want a better answer, please format your question so it can be easily read, include example inputs, outputs and database contents and make sure your code is properly indented.
All I can assume now is that your database field probably contains more than the data you want to match. Leading/tailing spaces or something?
The main problem in your query is in this section
like '%".$name."%'
Just remove % sign from your whole query where you have wrote and check your query may work
properly.
I need some help with a RegEx. The concept is simple, but the actual solution is well beyond anything I know how to figure out. If anyone could explain how I could achieve my desired effect (and provide an explanation with any example code) it'd be much appreciated!
Basically, imagine a database table that stores the following string:
'My name is $1. I wonder who $2 is.'
First, bear in mind that the dollar sign-number format IS set in stone. That's not just for this example--that's how these wildcards will actually be stored. I would like an input like the following to be able to return the above string.
'My name is John. I wonder who Sarah is.'
How would I create a query that searches with wildcards in this format, and then returns the applicable rows? I imagine a regular expression would be the best way. Bear in mind that, theoretically, any number of wildcards should be acceptable.
Right now, this is the part of my existing query that drags the content out of the database. The concatenation, et cetera, is there because in a single database cell, there are multiple strings concatenated by a vertical bar.
AND CONCAT('|', content, '|')
LIKE CONCAT('%|', '" . mysql_real_escape_string($in) . "', '|%')
I need to modify ^this line to work with the variables that are a part of the query, while keeping the current effect (vertical bars, etc) in place. If the RegEx also takes into account the bars, then the CONCAT() functions can be removed.
Here is an example string with concatenation as it might appear in the database:
Hello, my name is $1.|Hello, I'm $1.|$1 is my name!
The query should be able to match with any of those chunks in the string, and then return that row if there is a match. The variables $1 should be treated as wildcards. Vertical bars will always delimit chunks.
For MySQL, this article is a nice guide which should help you. The Regexp would be "(\$)(\d+)". Here's a query I ripped off the article:
SELECT * FROM posts WHERE content REGEXP '(\\$)(\\d+)';
After retrieving data, use this handy function:
function ParseData($query,$data) {
$matches=array();
while(preg_match("/(\\$)(\\d+)/",$query,$matches)) {
if (array_key_exists(substr($matches[0],1),$data))
$query=str_replace($matches[0],"'".mysql_real_escape_string($data[substr($matches[0],1)])."'",$query);
else
$query=str_replace($matches[0],"''",$query);
}
return $query;
}
Usage:
$query="$1 went to $2's house";
$data=array(
'1' => 'Bob',
'2' => 'Joe'
);
echo ParseData($query,$data); //Returns "Bob went to Joe's house
If you aren't sticky about using the $1 and $2 and could change them around a bit, you could take a look at this:
http://php.net/manual/en/function.sprintf.php
E.G.
<?php
$num = 5;
$location = 'tree';
$format = 'There are %d monkeys in the %s';
printf($format, $num, $location);
?>
If you want to find entries in the database, then you can use a LIKE statement:
SELECT statement FROM myTable WHERE statement LIKE '%$1%'
Which will find all statements that include $1. I'm assuming that the first number to replace will always be $1 - it doesn't matter, in that case, that the total number of wildcards is arbitrary, as we're just looking for the first one.
The PHP replacement is a little trickier. You could probably do something like:
$count = 1;
while (strpos($statement, "$" . $count)) {
$statement = str_replace("$" . $count, $array[$count], $statement);
}
(I've not tested that, so there might be typos in there, but it should be enough to give the general idea.)
The one downside is that it will fail if you have more than ten parameters in your string to replace - the first runthrough will replace the first two characters of $10, as it's looking for $1.
I asked a different, but similar, question, and I think the solution applies to this question just as well.
https://stackoverflow.com/a/10763476/1382779