MySQL Regex not matching first in comma delimited string of numbers - php

I'm using Wordpress and trying to find pages that contain a shortcode and its attributes.
Here's some example content in a page
[my-shortcode title="some text" style="grid"
post_ids="45724,1786,1889,1927,2613,32856,2976,2898,2372,2059"
image_id="61690"]
I currently have this MySQL query with a regex. $my_id = a specific number I set.
$query = 'SELECT ID,post_content from ' . $wpdb->posts .
' where post_type="page"
and post_content regexp "\[my-shortcode[^\]].*post_ids=\"[^\"].*' .
$my_id . '[^\"].*\"[^\]].*image_id=\"[0-9].*\"[^\]]?\]"';
This seems to work fine except for the first ID in the post_ids attribute. It never matches the first one, only IDs after the first one.
No doubt I'm doing something monumentally obvious but I'm sadly not a regex whizz.
I also appreciate there's other ways I could query the DB in Wordpress but for many other reasons I wont go in to right now this is the way I need to do it.
Any help very much appreciated!

Related

Mysql query keyword changes to unknown character set in php in case of Mobile devices

I am using a search query for selecting names in my DB by giving a keyword.
My query is
SELECT `engine4_core_search`.* FROM `engine4_core_search` WHERE ((`engine4_core_search`.`title` LIKE "%".$text."%"))
When give " cardiff " (cardiff comes in place of $text ) as my keyword and checking the query ..it displays like
SELECT `engine4_core_search`.* FROM `engine4_core_search` WHERE ((`engine4_core_search`.`title` LIKE 'Êrdiff%'))
Is there any method to solve this.
Thanks in advance.
It seems to be you have included jQuery-mobile (because tagged in it)
In some cases jQuery-mobile replaces some strings when they attached with different patterns like " %cardiff " . It may considers to be different string set
Just remove jQuery-mobile and try for your output......

"UPDATE WHERE NOT LIKE? "

I am trying to append strings to a field if they do not already exist with:
mysql_query("UPDATE gals4 SET tags = CONCAT(tags, '$instag') WHERE id = '$instagnum' AND tags NOT LIKE '$instag'");
This just appends to 'tags' regardless of weather it exists in the field or not. What am i doing wrong here?
To answer your immediate question, you must put the character % at the beginning and end of the match string:
"AND tags NOT LIKE '%$instag%'"
However, you should be aware that this is a terrible way to store data in an SQL database. There are at least three problems:
If you have tags that embed other tags ("cat" and "scat" for instance) you will find the wrong records unless you write very complicated comma-based searches.
These searches can never be indexed and will therefore become very slow as the number of records grows.
You cannot verify the tags used against a list of allowed tags, guarantee that only allowed tags are in the database, or easily present a list of existing or allowed tags.
The correct solution is to add at least one table to your database, called something like gals_tags, with columns galid and tag. Insert one record per tag into this table. If a gal has more than one tag, add one record for each tag.
You need another variable $instagwildcard which would be $instag but with a % after (and possibly before) $instag
As written, your select is looking for a string that is not an exact match to $instag - and I assume you are looking to also exclude strings that contain $instag somewhere in the string rather than an exact match....
$instagwildcard = "%" . $instag . "%";
mysql_query("UPDATE gals4 SET tags = CONCAT(tags, '$instag') WHERE id = '$instagnum' AND tags NOT LIKE '$instagwildcard'");
But I also agree with Larry's comment.

MySQL SELECT statement using PHP GET variable

I have a PHP script that is generating a MySQL select statement:
select * from words where word = 'Classic'
There is exactly one word in the words table with the variable word equal to Classic.
When my PHP page executes, I get no results from the query. If I echo the string that is being used to execute the query, cut and paste that into the SQL window in PHPMyAdmin in the database, I also get no results. However, if I re-type that EXACT string into the SQL window in PHPMyAdmin (with the same quote characters), I get the proper result of one row.
The word Classic from the select statement is gotten from a PHP GET (see code below). I can echo the $word variable, and get the correct result of 'Classic'. What am I doing wrong?
Here is my code:
<?php
require ('dbconnect.php');
$word = $_GET["word"];
$selectStr = "SELECT * FROM words WHERE word = '" . $word . "'";
if ($results = MySQL($dbName, $selectStr))
{
$rowCount = MySQL_NUMROWS($results);
}
$resultRow = MYSQL_FETCH_ROW($results);
$wordID = $resultRow[0];
?>
Please, please, please sanitize that word. mysql_real_escape_string() should do the trick.
$selectStr = "SELECT * FROM words WHERE word LIKE '" . $sanitized_word_i_promise . "'"; should work :)
Just to explain: "=" should work for exact matches. This includes uppercase / lowercase, spaces etc. You should probably trim that result first too, before using it in the query.
If you have foo stored in the database (note the space at the end) - it won't match foo, without a space. You'll want to use LIKE 'foo%' - probably.
Either way, Sourabh is right, although performance wise, this isn't a big hit when trying to match exact strings, you should look for the problem in other places first (such as, is the item in the database an exact match?).
First off you should not take any user input and directly input it into a query without sanitizing it, or using a prepared statement.
Now that we've gotten that out of the way: have you tried doing a strcmp() with the variable and your string written in? Such as
echo strcmp($_GET['word'], "Classic")
If you get a result other than 0 it means they are not the same, most likely there will be a whitespace of some sort in the $_GET variable. use trim() on it to take out whitespace. Also could be a case sensitivity issue as well.

SELECTing MySQL rows with unusual characters using PHP and querystrings

Table name Styles.
Referenced Column: Style
Coding with PHP 5.
Problem:
My SELECT query to MySQL returns 0 rows.
I'm using the column name in querystring as identifier (something like example.com.php?style=paper-pencils). For SEO purposes I've removed any odd characters and replaced spaces with '-'. Using url rewrite to end up with example.com/paper-pencils.
Working on a database I inherited which uses characters such as '&' or ':' in the Style column. On the database side, the Style column would contain a row with something like "Paper & Pencils" as compared to my slugged version of "paper-pencils".
Things I've Tried:
I de-slug the url so i end up with 'paper pencils' (see below in query example).
I tried
SELECT * ,REPLACE( 'Style', '&', ' ' ) AS Style, REPLACE( 'Style', ':', ' ' ) AS Style FROM Styles
WHERE Style = 'paper pencils'
to no avail. The query I have runs fine, it just comes back with 0 results.
My next step would be to do a PHP SWITCH statement. Something like
case: $_GET['style'] = 'paper-pencils'
$DBstyle = 'Paper & Pencils' but I feel like there has to be some other way around it. I have 30 different possibilities and would prefer something better.
Any suggestions on how I can account for these unusual characters with random occurrences?
Maybe you can add another column to this table called style_slug. This column will contain the slugged version that you use in your urls and will allow you to retrieve the Style column in your query.
Just like Gohn said or, a better one - use an approach which is used on this site - have both an unique identifier and a slug in the url.
example.com/2356356/paper-pencils
will cajole SEO and make your life easy.

How to get the same search results regardless white space in the search term?

I am trying to make a search box for an ecommerce website.
The search works as follows
When a user searches for a product, the search value is being sent to a file called searchResults.php using post method via ajax
$searchVal=$_POST['searchVal'];
And then its being searched in the database from a table named product by the following query
$searchResult = mysql_query("SELECT * FROM products WHERE name LIKE '$searchVal'")
and the results are sent back as ajax response by the following if condition
if($searchResult){
echo "result";
}
else{
echo "No products found";
}
Above all everything works fine as expected.
lets assume an user is searching for cellphones and he/she types cell phone . But we have products only for category cellphones and not for cell phone. So it results No products found even though the records for cellphones are present.
I want to make it search regardless the white space, singular or plural . How can i do that ?
The right way to implement a search engine is to maintain a separate table of words and links to the record they appear in. Then....
$qry="SELECT p.*, COUNT(*)
FROM products p
INNER JOIN srchwords s
ON p.id=s.product_id ";
$searchVals=explode(' ',$_POST['searchVal']);
foreach ($searchvals as $k=>$s) {
$searchvals[$k]="'" . mysql_real_escape_string(trim($s)) . "'";
}
$qry.="WHERE s.word IN (" . implode(",",$searchvals) . ") ORDER BY COUNT(*) DESC";
An ugly and innefficient hack would be:
$qry="SELECT p.*
FROM products p";
$join=" WHERE "
$searchVals=explode(' ',$_POST['searchVal']);
foreach ($searchvals as $k=>$s) {
$qry.=$join . " p.desc LIKE '%" . mysql_real_escape_string(trim($s)) . "%'
$join=' OR ';
}
Both methods still don't not cater for plurals (just add an additional comparison for words ending in S, removing the S). You should also clean up the string to remove multiple spaces and punctuation (/^[a-z0-9 ]/i).
Or just use one of the many, well written off-the-shelf search engine solutions (e.g. the mnogo engine or Google's site search service).
Step 1: remove leading and trailling spaces:
$searchResult = mysql_query("SELECT * FROM products WHERE name LIKE trim('$searchVal')")
Step 2: replace existent spaces by '%' (it's wildcard in LIKE syntax):
$searchResult = mysql_query("SELECT * FROM products WHERE name LIKE str_replace(trim('$searchVal'), ' ', '%'")
A first step would be to explode() the search term on spaces: $terms = explode(' ', $query) and then do a 'SELECT * FROM products WHERE name LIKE "%'.$terms[0].'%" AND name LIKE "%'.$terms[1].'%" ...'.
Of course, this doesn't really solve your plurals issue.. Also, it can be very, very slow because MySQL can't use indexes on LIKE queries starting with a wildcard.
Another course of action could be to just have an "aliases" table that would look something like this:
cellphone | cell phone
cellphone | cell phones
cellphone | cellphones
...
Then you would replace the all occurances in a search query with the one on the left before querying the database for it.
The third and best and most complicated way is to use an index table. You wouldn't want to write that yourself, but I'd bet there are some great solutions out there. Personally, I'm using Doctrine, which has this feature built in.
You can use trim() in php to strip whitespace (or other characters) from the beginning and end of a string

Categories