Use like with PDO on JSON-String - php

Actualy I know how to use LIKE statement with PDO
Now I have a DB-Table called e.g. foobar
foobar contains a JSON-String like:
{"firstname":"foo","email":"aaa#aaa.aa","lastname":"bar"}
Now before I call my INSERT on the table I want to check if the Email is already in use.
$pdo->query("SELECT * FROM myTable WHERE foobar LIKE ?", array('%' . $email . '%'));
as you can see, I pass the email into the pdo query.
Notice ->query is my custom function that handles some stuff. In this case its not important to know what happens.
The problem I have is:
If the entry like above exists then its not possible anymore to add an email thats like:
aa#aaa.aa
^^....only two A's
So I thought I can simply change
array('%' . $email . '%')
to
array('%"' . $email . '"%')
but this doesnt work. Is there a way I can check the whole string part ?
{"firstname":"foo","email":"aaa#aaa.aa","lastname":"bar"}

If you can't break the JSON fields into their own columns, then I would suggest a JSON column type. It's native to MySQL, super fast for JSON of this size, and no more difficult to use than something like jq on the command line.
If that's not an option, I would use a REGEXP:
mysql> select * from foobar;
+-----------------------------------------------------------+
| json |
+-----------------------------------------------------------+
| {"firstname":"foo","email":"aaa#aaa.aa","lastname":"bar"} |
| {"firstname":"FOO","email":"aa#aaa.aa","lastname":"BAR"} |
+-----------------------------------------------------------+
mysql> select * from foobar where json regexp '"email":"aa#aaa.aa"';
+----------------------------------------------------------+
| json |
+----------------------------------------------------------+
| {"firstname":"FOO","email":"aa#aaa.aa","lastname":"BAR"} |
+----------------------------------------------------------+
1 row in set (0.00 sec)
This is serviceable, but hardly bullet-proof and, to borrow an excellent turn of phrase, will murder performance on anything but trivial row sets.

Related

How to escape a # within a SQL CONCAT for anchor in URL

I'm setting up a database query to access and link to comments, but I am having trouble escaping the # symbol within the CONCAT. Here is my current query:
SELECT c.subject, CONCAT('node/', c.nid, '/comment-', c.cid) FROM {comments} c WHERE c.subject LIKE LOWER(:like_word)
Which creates urls like this: node/1234/comment-1234
I need to include the # to create a url like so: node/1234/#comment-1234 but that doesn't work due to the # sign.
SELECT c.subject, CONCAT('node/', c.nid, '/#comment-', c.cid) FROM {comments} c WHERE c.subject LIKE LOWER(:like_word)
Can you provide some more details? You say it "doesn't work due to the # sign". How does it not work? Do you get an error? Is the resulting string not what you expected?
I tried a test here on MySQL 5.5 and got what seems like a normal response:
mysql> select concat('foo/', 'bar', '/#comment');
+------------------------------------+
| concat('foo/', 'bar', '/#comment') |
+------------------------------------+
| foo/bar/#comment |
+------------------------------------+
1 row in set (0.00 sec)

how to trace duplicate data

I would like to ask something here.
now I make form that insert data into table.
this table kemaskini that already have
+------+----------+----------+
| no | Item | kuantiti |
+------+----------+----------+
| 1 | Speaker | 10 |
+------+----------+----------+
| 2 | Laptop | 10 |
+------+----------+----------+
| 3 | Mouse | 10 |
+------+----------+----------+
when I type "Speaker" in form then I submit it.
it trace and say try again. it because already have.
coding that I write here. it only trace row 1 of table kemaskini.
when I type "Laptop" in form then I submit it.
it insert normally.
i more thing how I can trace "Speaker" and "speaker" are same.
if (isset($_POST['submit']))
{
$result = mysql_query("SELECT Item FROM kemaskini");
$test = mysql_fetch_array($result);
$trace=$test['Item'];
if($_POST['Item']==$trace)
{
echo "Try Again";
}
else
{
$item=$_POST['Item'] ;
$kuantiti= $_POST['kuantiti'] ;
mysql_query("INSERT INTO `kemaskini`(Item,kuantiti)
VALUES ('$item','$kuantiti')");
header("Location: kemaskini.php");
}
}
The reason for that is because you are not looping the result from mysql_fetch_array() that is why you are only checking for the first value of the result. If you don't want to Iterate, you can change the query into:
$itemToSearch = "Speaker";
$result = mysql_query("SELECT COUNT(*) result
FROM kemaskini
WHERE Item = '$itemToSearch'")
which will give you the total number of items found,
$test = mysql_fetch_array($result);
$trace = $test['result'];
if($trace > 0)
{
echo "Try Again";
}
else
{
// insert value
}
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?
Regarding, how can you trace "Speaker" and "speaker" are the same, you can use the upper() or lower() function that most database engines support. I don't work with mysql so I am going on an assumption here. Your check would be something like this:
select count(*) records
from kemaskini
where lower(item) = 'speaker'
Having said that, I have to warn you that using functions in the where clause like this make your queries run slower.
If JW's comment about PreparedStatements includes using query parameters (I don't work with php either), it's very good advice. Not only do they increase the security of your applications, but they escape special characters such as apostrophes. Since you are doing a character search, you would not want your query to crash if the user submitted something like "Dave's keyboard" to your application.

Mysql string input with formatting

I am a beginner at MySQL and I am having a little trouble with the correct formatting for a cell in my table.
I have the data type set to TEXT so there is plenty of space for a few small paragraphs within the cell however my problem is, how do I format the paragraph with apostrophes, quotes, colons, and other punctuation that I am inserting into that cell via command line (MAC)?
This is what the column values are:
joke TEXT NOT NULL,
I want to insert this example joke into the table:
Husband says: "When I'm gone you'll never find another man like me".
Wife replied: "What makes you think I'd want another man like you!"
How do I write it into command line so it will display the exact formatting or at least something close. My command line entry looks like this:
INSERT INTO jokes
(date_submitted, source, joke_style, joke)
VALUES
(NOW(), 'www.example.com','Blonde', 'Joke would go here with (: ' ,) and so on.');
Do I escape the apostrophes with \'? What do I do with the rest of the punctuation, and how do I store line breaks?
Use mysql_real_escape_string() or switch to PDO and use PDO::prepare() with placeholders.
Example:
$sth = $pdo->prepare('INSERT INTO jokes ... VALUES (NOW, :joke, ...)');
$sth->execute(array(':joke' => $joke));
If you need to write commands manually, you should escape ' as \', and the newline character is \n. For more details about how strings are escaped in MySQL, see the manual section about string literals.
heres an excerpt from the manual
The following SELECT statements demonstrate how quoting and escaping work:
mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+
mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+
mysql> SELECT 'This\nIs\nFour\nLines';
+--------------------+
| This
Is
Four
Lines |
+--------------------+
mysql> SELECT 'disappearing\ backslash';
+------------------------+
| disappearing backslash |
+------------------------+

Insert Blobs in MySql databases with php

I am trying to store an image in the DataBase, for some reason it doesn't seem to work. Here's the structure of my table.
mysql> describe ImageStore;
+---------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+----------+------+-----+---------+-------+
| ImageId | int(11) | NO | PRI | NULL | |
| Image | longblob | NO | | NULL | |
+---------+----------+------+-----+---------+-------+
2 rows in set (0.01 sec)
And here is my query which inserts the image or at least thats what it should:
//Store the binary image into the database
$tmp_img = $this->image['tmp_name'];
$sql = "INSERT INTO ImageStore(ImageId,Image)
VALUES('$this->image_id','file_get_contents($tmp_image)')";
mysql_query($sql);
If I print the value of file_get_contents($tmp_image), then there is a tons of data on the screen. But this value doesn't get stored in the database and that is the issue that I'm facing.
Problem
$sql = "INSERT INTO ImageStore(ImageId,Image)
VALUES('$this->image_id','file_get_contents($tmp_image)')";
This creates a string in PHP named $sql. Forget about MySQL for a minute, because you're not executing any query yet. You're just building a string.
The magic of PHP means that you can write a variable name — say, $this->image_id — inside the double quotes and the variable still gets magically expanded.
This functionality, known as "variable interpolation", does not occur for function calls. So, all you're doing here is writing the string "file_get_contents($tmp_image)" into the database.
Solution (1)
So, to concatenate the result of calling file_get_contents($tmp_image), you have to jump out of the string and do things explicitly:
$sql = "INSERT INTO ImageStore(ImageId,Image)
VALUES('$this->image_id','" . file_get_contents($tmp_image) . "')";
(You can see even just from the syntax highlighting how this has worked.)
Solution (2)
Now the problem you have is that if the binary data contains any ', your query is not valid. So you should run it through mysql_escape_string to sanitize it for the query operation:
$sql = "INSERT INTO ImageStore(ImageId,Image)
VALUES('$this->image_id','" . mysql_escape_string(file_get_contents($tmp_image)) . "')";
Solution (3)
Now you have a really big string, and your database is getting bulky.
Prefer not storing images in databases, where you can help it.
To expand on Tomalak's comment, you can't run a function inside of quotes.
Try:
$sql = "INSERT INTO ImageStore(ImageId,Image)
VALUES('{$this->image_id}','".file_get_contents($tmp_image)."')";
try this:
$tmp_img = $this->image['tmp_name'];
$sql = "INSERT INTO ImageStore(ImageId,Image)
VALUES('$this->image_id','" . addslashes(file_get_contents($tmp_image)) . "')";
mysql_query($sql);
As mentioned you are just saving the string "file_get_contents($tmp_image)" into the db
but you need to run the function file_get_contents instead
dont forget to hash the image using a hashing algorithm such as base64_encode before saving it to the db.

Searching for a partial match in a SQL database with PHP

I have a php file that search a SQL database. It takes a string from a textbox and tries to match it to various attributes for the database. Here is the code that performs the searched:
if ($filter['meta_info']) {
$search_string = $filter['meta_info'];
unset($filter['meta_info']);
$m_intSortField = null;
$m_strWhere .= (($m_strWhere) ? " AND " : "")."(MATCH (`courses`.`assigned_id`,`courses`.`title`,`courses`.`author`,`courses`.`keywords`,`courses`.` abstract`,`courses`.`objective`,`courses`.`summary`,`courses`.`copyright`,`courses`.`notes`) AGAINST ('".mysql_escape_string($search_string)."' IN BOOLEAN MODE))";
}
My problem is, I want it to return courses that have a partial match to the assigned ID not just a complete match. Anyone know how I could do this?
Turn off strict mode on your mysql options, or use LIKE.
SELECT id,name from LESSONS where name LIKE "English%";
returns
| id | Name
| 2 | English Literature
| 8 | English Language

Categories