PHP Regex pattern needed for MySQL database manupilation - php

I have some columns in my table, descriptions column contains some information like;
a1b01,Value 1,2,1,60|a1b01,Value2,1,1,50|b203c,Value 1,0,2,20
with a SQL command, i need to update it.
In there, I'll use a PHP function for updating, if first and second parameters exist in current records (in description column) together.
Eg: if user wants to change the value of description that includes a1b01,Value 1 I'll execute a SQL command like that;
function do_action ($code,$value,$new1,$new2,$newresult) {
UPDATE the_table SET descriptions = REPLACE(descriptions, $code.','.$value.'*', $code.','.$value.','.$new1.','.$new2.','.$newresult)";
}
(star) indicates that, these part is unknown (This is why i need a regex)
My question is : how can i get
a1b01,Value 1,2,1,60|
part from below string
a1b01,Value 1,2,1,60|a1b01,Value2,1,1,50|b203c,Value 1,0,2,20
via regex, but a1b01 and Value 1 should be get as parameter.
I just want that; when I call do_action like that;
do_action ("a1b01","Value 1",2,3,25);
record will be : a1b01,Value 1,2,3,25|a1b01,Value2,1,1,50|b203c,Value 1,0,2,20(first part is updated...)

You don't necessarily need to use a regular expression to do this, you could use the explode function since it is all delimited
So you could do as follows:
$descriptionArray = explode('|', $descriptions); //creates array of the a1b01,Value 1,2,1,60 block
//then for each description explode on ,
for($i = 0; i < count($descriptionArray); $i++){
$parameters = explode(',', $descriptionArray[$i]);
do_action ($parameters[0],$parameters[1],$parameters[2],$parameters[3],$parameters[4]);
}

Related

How can I str_replace partially in PHP in a dynamic string with unknown key content

Working in WordPress (PHP). I want to set strings to the database like below. The string is translatable, so it could be in any language keeping the template codes. For the possible variations, I presented 4 strings here:
<?php
$string = '%%AUTHOR%% changed status to %%STATUS_new%%';
$string = '%%AUTHOR%% changed status to %%STATUS_oldie%%';
$string = '%%AUTHOR%% changed priority to %%PRIORITY_high%%';
$string = '%%AUTHOR%% changed priority to %%PRIORITY_low%%';
To make the string human-readable, for the %%AUTHOR%% part I can change the string like below:
<?php
$username = 'Illigil Liosous'; // could be any unicode string
$content = str_replace('%%AUTHOR%%', $username, $string);
But for status and priority, I have different substrings of different lengths.
Question is:
How can I make those dynamic substring be replaced on-the-fly so that they could be human-readable like:
Illigil Liosous changed status to Newendotobulous;
Illigil Liosous changed status to Oldisticabulous;
Illigil Liosous changed priority to Highlistacolisticosso;
Illigil Liosous changed priority to Lowisdulousiannosso;
Those unsoundable words are to let you understand the nature of a translatable string, that could be anything other than known words.
I think I can proceed with something like below:
<?php
if( strpos($_content, '%%STATUS_') !== false ) {
// proceed to push the translatable status string
}
if( strpos($_content, '%%PRIORITY_') !== false ) {
// proceed to push the translatable priority string
}
But how can I fill inside those conditionals efficiently?
Edit
I might not fully am clear with my question, hence updating the query. The issue is not related to array str_replace.
The issue is, the $string that I need to detect is not predefined. It would come like below:
if($status_changed) :
$string = "%%AUTHOR%% changed status to %%STATUS_{$status}%%";
else if($priority_changed) :
$string = "%%AUTHOR%% changed priority to %%PRIORITY_{$priority}%%";
endif;
Where they will be filled dynamically with values in the $status and $priority.
So when it comes to str_replace() I will actually use functions to get their appropriate labels:
<?php
function human_readable($codified_string, $user_id) {
if( strpos($_content, '%%STATUS_') !== false ) {
// need a way to get the $status extracted from the $codified_string
// $_got_status = ???? // I don't know how.
get_status_label($_got_status);
// the status label replacement would take place here, I don't know how.
}
if( strpos($_content, '%%PRIORITY_') !== false ) {
// need a way to get the $priority extracted from the $codified_string
// $_got_priority = ???? // I don't know how.
get_priority_label($_got_priority);
// the priority label replacement would take place here, I don't know how.
}
// Author name replacement takes place now
$username = get_the_username($user_id);
$human_readable_string = str_replace('%%AUTHOR%%', $username, $codified_string);
return $human_readable_string;
}
The function has some missing points where I currently am stuck. :(
Can you guide me a way out?
It sounds like you need to use RegEx for this solution.
You can use the following code snippet to get the effect you want to achieve:
preg_match('/%%PRIORITY_(.*?)%%/', $_content, $matches);
if (count($matches) > 0) {
$human_readable_string = str_replace("%%PRIORITY_{$matches[0]}%%", $replace, $codified_string);
}
Of course, the above code needs to be changed for STATUS and any other replacements that you require.
Explaining the RegEx code in short it:
/
The starting of any regular expression.
%%PRIORITY_
Is a literal match of those characters.
(
The opening of the match. This is going to be stored in the third parameter of the preg_match.
.
This matches any character that isn't a new line.
*?
This matches between 0 and infinite of the preceding character - in this case anything. The ? is a lazy match since the %% character will be matched by the ..
Check out the RegEx in action: https://regex101.com/r/qztLue/1

Adding an integer value into string in laravel

Hello Every one,
I have an issue that is, I want to add an integer into a string for example I have two text field one is called series start and the other one is called series end now if user enters
FAHD1000001 into series start field
AND
FAHD1000100 into series end field
the algorithm should store 100 values into the database with increment into the each entry that is going to store into the database. i.e
FAHD1000001, FAHD1000002, FAHD1000003, ........., FAHD1000100
Is it possible to do so, if yes then how. Please help me
You have to do something like this but there is a loop hole if you have any numeric value in name like F1AHD00001 than it will not work
$str1 = $request['start'];
$str2 = $request['end'];
$startint=preg_replace("/[^0-9]/","",$str1);
$endint=preg_replace("/[^0-9]/","",$str2 );
$words = preg_replace('/[[:digit:]]/', '', $str1);
for($i=$startint;$i<$endint;$i++){
$newstring=$words.$i;
//Save this new String
}

PHP search MySQL

I've got this code:
function searchMovie($query)
{
$this->db->where("film_name LIKE '%$query%'");
$movies = $this->db->get ("films", 40);
if($this->db->count > 0)
{
return $movies;
}
return false;
}
Javascript code from my submit form button strips all special characters like ; : ' / etc. from query string, and then redirects user to search uri (szukaj/query). So for example if film_name is Raj: wiara, and user searches for raj: wiara, the query looks like raj wiara and user doesn't get any results. I was thinking about exploding query into single words and then foreach word do a SELECT from db, but it would give multiple results of same movie. Don't want to change the javascript code, and I think I can't make that film names without the special characters like :.
Or maybe create another column in db for film_keywords and add there all words of movie separated by , or something and then search this column?
MySQL's Full Text Search functions are your friend here:
http://dev.mysql.com/doc/refman/5.7/en/fulltext-search.html
Will return a series of matches and give a score so you return in best-match order.
Warning: $this->db->where("film_name LIKE '%$query%'"); is open to SQL injection. Anyone can circumnavigate the JavaScript so you must always clean up input server-side. This is best done using the DB functions as well, not just stripping characters - so check whatever library you are using in order to do this.
You could indeed explode your string, using this answer's solution.
function searchMovie($query)
{
$queries = preg_split('/[^a-z0-9.\']+/i', $query);
foreach ($queries as $keyword){
$this->db->where("film_name LIKE '%$keyword%'");
}
$movies = $this->db->get ("films", 40);
if($this->db->count > 0)
{
return $movies;
}
return false;
}
This will create multiple ANDconditions for your db where, so the result will be filtered.

Converting a user inputted boolean search string into mySQL

I've got a database search field where I want the user to be able to input simple boolean logic and have that translated to a mySQL search string.
So for instance if the user inputs: (php AND mysql) OR ajax
I'd like to convert that to:
((c.Skillset LIKE '%php%' AND c.Skillset LIKE %mysql%) OR c.Skillset LIKE '%ajax%')
Is there a fairly simple way of doing this? I'm having particular trouble coming up with a solution for the brackets, if it wasn't for that it would be quite straightforward.
The following assumes you have some constant called SQL_PREFIX_STRING defined.
$string = '(php AND mysql) OR java';
preg_match_all('/[a-z]+/', $string, $skills); // puts the skills in an array
$skills = $skills[0]; // shift array to get the matching values
array_walk($skills, function (&$skill) {$skill = '%'.$skill.'%';}); // add wildcards to parameters
$query_string = preg_replace('/[a-z]+/', 'c.Skillset LIKE ?', $string); // create the ? parameters for the SQL string
$pdoStatement = $pdo->prepare(SQL_PREFIX_STRING.$sql); // prepare
$pdoStatement->execute($skills); // execute

Remove values in comma separated list from database

I have a table in my MySQL database called 'children'. In that table is a row called 'wishes' (a comma separated list of the child's wishlist items). I need to be able to update that list so that it only removes one value. i.e. the list = Size 12 regular jeans, Surfboard, Red Sox Baseball Cap; I want to remove Surfboard.
My query right now looks like this
$select = mysql_query('SELECT * FROM children WHERE caseNumber="'.$caseNum.'" LIMIT 1 ');
$row = mysql_fetch_array($select);
foreach ($wish as $w) {
$allWishes = $row['wishes'];
$newWishes = str_replace($w, '', $allWishes);
$update = mysql_query("UPDATE children SET wishes='$newWishes' WHERE caseNum='".$caseNum."'");
}
But the UPDATE query isn't removing anything. How can I do what I need?
Using these user-defined REGEXP_REPLACE() functions, you may be able to replace it with an empty string:
UPDATE children SET wishes = REGEXP_REPLACE(wishes, '(,(\s)?)?Surfboard', '') WHERE caseNum='whatever';
Unfortunately, you cannot just use plain old REPLACE() because you don't know where in the string 'Surfboard' appears. In fact, the regex above would probably need additional tweaking if 'Surfboard' occurs at the beginning or end.
Perhaps you could trim off leading and trailing commas left over like this:
UPDATE children SET wishes = TRIM(BOTH ',' FROM REGEXP_REPLACE(wishes, '(,(\s)?)?Surfboard', '')) WHERE caseNum='whatever';
So what's going on here? The regex removes 'Surfboard' plus an optional comma & space before it. Then the surrounding TRIM() function eliminates a possible leading comma in case 'Surfboard' occurred at the beginning of the string. That could probably be handled by the regex as well, but frankly, I'm too tired to puzzle it out.
Note, I've never used these myself and cannot vouch for their effectiveness or robustness, but it is a place to start. And, as others are mentioning in the comments, you really should have these in a normalized wishlist table, rather than as a comma-separated string.
Update
Thinking about this more, I'm more partial to just forcing the use of built-in REPLACE() and then cleaning out the extra comma where you may get two commas in a row. This is looking for two commas side by side, as though there had been no spaces separating your original list items. If the items had been separated by commas and spaces, change ',,' to ', ,' in the outer REPLACE() call.
UPDATE children SET wishes = TRIM(BOTH ',' FROM REPLACE(REPLACE(wishes, 'Surfboard', ''), ',,', ',')) WHERE caseNum='whatever';
Not exactly a direct answer to your question, but like Daren says it's be better having wishes as its own table. Maybe you could change your database schema so you have 3 tables, for instance:
children
-> caseNum
-> childName
wishes
-> caseNum
-> wishId
-> wishName
childrensWishes
-> caseNum
-> wishId
Then to add or delete a wish for a child, you just add or delete the relevant row from childrensWishes. Your current design makes it difficult to manipulate (as you're finding), plus leaves you at risk for inconsistent data.
As a more direct answer, you could fix your current way by getting the list of wishes, explode() 'ing them, removing the one you don't want from the array and implode() 'ing it back to a string to update the database.
Make wishes table have this format:
caseNumber,wish
Then you get all of a child's wishes like this:
SELECT * FROM children c left join wishes w on c.caseNumber = w.caseNumber WHERE c.caseNumber= ?
Removing a wish becomes:
DELETE from wishes where caseNumber = ?
Adding a wish becomes:
INSERT into wishes (caseNumber,wish) values (?,?)
Returning one wish becomes:
SELECT * FROM children c left join wishes w on c.caseNumber = w.caseNumber WHERE c.caseNumber= ? LIMIT 1
Having the wishes indexed in an array which is thereafter serialized could be an idea, otherwise you would need to retrieve the string, slice it, remove the part you don't want, then concatenate the remains. This can be done by using the explode() function.
If you were to use an array, you would retrieve the array and then sort through it with a loop like this:
// Wishes array:
// Array (
// [0] Regular Jeans
// [1] Surfboard
// [2] Red Sox Baseball Cap
// )
$wishes = $row['wishes']; // This is a serialized array taken from the database
$wishes = unserialize($wishes);
foreach ($wishes as $key => $value) {
if ($value == 'Surfboard') {
unset($wishes[$key]);
break;
}
}
$wishes = serialize($wishes);
// Update database
Keep in mind that index [1] now won't exist in the array, so if you wish to have a clean array you should loop through the array and make it create a new array by itself:
foreach ($wishes as $wishes) {
$newArray[] = $wishes;
}
I think the best answer to such issue is here
The best way to remove value from SET field?
query should be like this which covers the ,value or value, or only value in the comma separated column
UPDATE yourtable
SET
categories =
TRIM(BOTH ',' FROM
REPLACE(
REPLACE(CONCAT(',',REPLACE(col, ',', ',,'), ','),',2,', ''), ',,', ',')
)
WHERE
FIND_IN_SET('2', categories)
Here you can have your condition in where clause. for more details refer above link.
You can create function like this:
CREATE FUNCTION `remove_from_set`(v int,lst longtext) RETURNS longtext CHARSET utf8
BEGIN
set #lst=REPLACE(#lst, ',,', ',');
set #lng=LENGTH(#lst) - LENGTH(REPLACE(#lst, ',', ''))+1;
set #p=find_in_set(#v,#lst);
set #l=SUBSTRING_INDEX( #lst, ',', #p-1);
set #r=SUBSTRING_INDEX( #lst, ',', #p-#lng);
IF #l!='' AND #r!='' THEN
return CONCAT(#l,',',#r);
ELSE
RETURN CONCAT(#l,'',#r);
END IF;
END
Using:
SELECT remove_from_set('1,,2,3,4,5,6',1)

Categories