Multiple replace statements alternatively replace specific characters - php

I need to remove some all numbers, some special characters and specific parts of text from my database. I have a script that can remove one character at a time but I would like to remove all characters in one time.
The characters and text I need to remove look like this: Dollar, Sterling, Page, .p, ~, . and then the numbers 1-9
For example: I have an entry right now that looks like this: This is a great book, 595 pages .p 595 and costs only $ 54.95
I need to update it so it looks like this: This is a great book, and costs only.
Below is the code snippet for the replace feature I use. I would like to use this set up as I want it to work with the rest of the script. $table is the name, $field is the column name, $search is the value that needs to be replaced and $replace is the value to replace with (blank in my case)
if($typeOK) {
// CREATE UNIQUE HANDLE FOR update_sql_array
$handle = $table.'_'.$field;
if($queryType=='replace') {
$sql[$handle]['sql'] = 'UPDATE '.$table.' SET '.$field.' = REPLACE('.$field.',\''.$search.'\',\''.$replace.'\')';
} elseif($queryType=='') {
$sql[$handle]['sql'] = 'UPDATE '.$table.' SET '.$field.' = REPLACE('.$field.',\''.$keyword1.'\',\''.$replace1.'\')';
}
I can post the whole script if needed.
I have tried using multiple replace statements but when I do so it only executes the last replace statement ignoring the first one.

Some databases support a function called TRANSLATE, but unfortunately, MySQL is not one of them. You can do it with nested replaces:
set field = replace(replace(replace( . . . (field, '0', ''), '1', '') . . . , '9', '')
Not elegant, but it works.
The "..." are intended to show additional calls to replace, as in the following sequence:
set field = replace(field, '0', '')
set field = replace(replace(field, '0', ''), '1', '')
set field = replace(replace(replace(field, '0', ''), '1', ''), '2', '')
. . .

Related

MySQL UPDATE and INSERT both returning error message about bad syntax, but it is correct syntax when trying it on phpMyAdmin

I have a PHP program that will either INSERT a new row, or UPDATE the existing one if it's already there. When running on a browser, it returns errors.
But, the actual call runs OK on phpMySQL - no error reported and row is updated.
"Errormessage: 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 '"updated", `conditions` =" ",' at line 1.
Code to connect to mySQL and make the update or insert is very simple
require_once ('mysqli_connect.php');
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error($dbcon);
exit ;
}
Then I make the actual body of the call, which produces variable $call containing this (example is for UPDATE):
UPDATE `deal` SET `deal_lotus_source` = "updated", `conditions` =" ", `termsnotes` = " ", `walkprovision` = " ", `sector` = "Application Software", `industry` = "Airconditioning", `tgt` = "Bcd", `acq` = "E", `dtstart` = "2015/03/08" , `dtclose` = "2015/03/23", `dtexdivtgt` = "2015/03/17", `dtexdivacq` = "2015/03/17", `dtexdivtgtexp` = "2015/03/17", `dtexdivacqexp` = "2015/03/17", `acq` = "E",`stat`= "Closed",`acqtype`= "Domestic",`dealtype`= "Acquisition of Private Company Cash-Stoc",`analyst`= "Fred Blogs",`tgttkr`= "ABC",`tgtx`= "C",`tgtprec`= "$",`tgtpret`= "1",`tgtshrout`= "2",`acqtkr`= "D",`acqx`= "F",`acqprec`= "$",`acqpret`= "3",`acqshrsout`= "4",`dlvalue`= "5",`eacls`= "Actual",`tgtlaw`= "",`acqlaw`= "",`tgtbank`= "",`acqbank`= "",`tgtshrsoutfd`= "6",`acqshrsoutfd`= "7",`tgtdebt`= "8",`acqdebt`= "8",`suppress`= "0",`pricingp`= "",`terminate`= " ",`divstattgt`= "",`divstatacq`= "",`divfreqtgt`= "Quarterly",`divfreqacq`= "Quarterly",`divcurrtgt`= "$",`divcurracq`= "$",`divamttgt`= "0.000",`divamtacq`= "0.000", `cos` = "", `mot` = "" WHERE deal_id =578
and the code to update (or insert) is
if (!mysqli_query($dbcon, $call)) {
printf("Errormessage: %s\n", mysqli_error($dbcon));
die;
}
Any ideas?
You have to use single quotes arround the values:
UPDATE `deal` SET `deal_lotus_source` = 'updated', `conditions` =' ', `termsnotes` = ' ', `walkprovision` = ' ', `sector` = 'Application Software', ...
Quotes in PHP can be confusing, because depending on which type of quote you use there are (different rules](http://www.trans4mind.com/personal_development/phpTutorial/quotes.htm). The most important things (in this case) to keep in mind are these 2:
* If you have a variable ($var) inside double-quotes ("$var") then it will get substituted (your string will now contain value) whereas if it is in single-quotes ('$var') then it will NOT get substituted (it remains in your string as $var)
* If you are need single-quotes as part of your string then use double-quotes around the string. ("I don't like contractions and I can't bear to use them.") If you need double-quotes as part of your string then use single quotes to surround the string. ('He said, "Hello, Dear!" and she slapped him.')
You are using double quotes (note the values you want to compare conditions and termsnotes and etc. to) but you are going to want to change to single-quotes inside the string so you can surround the whole thing with double-quotes. This also has the advantage of allowing you to use variables inside it.
$call = "UPDATE `deal`
SET `deal_lotus_source` = 'updated',
`conditions` =' ',
`termsnotes` = ' ',
`walkprovision` = ' ',
...
`mot` = ''
WHERE deal_id =578";
Note that the only double-quotes in that whole line of code are the ones at the very beginning and ending of the string. If you want to put a double-quote inside the string then you would have to put a backslash in front of it.
One very important step when you are constructing a query in a string (especially if you are getting errors with it) is to actually look at it. Use echo "call=<pre>$call</pre><br />\n"; and then look very carefully at all your quotes and etc. You can actually copy/paste the results of this echo into phpMyAdmin and see if the actual query works in your sql tab - this is a great test.
In summary, quotes in PHP are very consistent and very powerful, but they do have the potential to change your string during the process of assigning the string to a variable. It's very important to verify that the string after assignment is the string that you expect.

Replace characters in MySQL query result PHP

Couldn't find an exact answer to this question on here, though it may be simple (if there is an answer please point me in the right direction).
I am pulling some data from MySQL and some of the characters are causing the data not to be displayed at the end point. I therefore need to single out these specific characters and replace them with a permitted character. Specifically I need to change & , ' and + . I have to do this working from this query:
$query = "select * from data where a_data_id=".$ID." AND a_discard_data_from!=1";
I was wondering if I can add to this string, or after this string, some rule to replace instances & , ' or + with another character/s.
Thanks for looking!
NOTE: There is no problem with the string above, it is functioning fine, I just want to add to it or after it some type of code that will replace certain characters in the data pulled from the query
Surrounding Code:
$arr="";
$main_arr="";
$query = "select * from data where a_data_id=".$ID." AND a_discard_data_from!=1";
$query .=" and last_update >= " . '"' . $dataDate . '"';
$table = mysql_query($query);
if (mysql_num_rows($table) > 0) {
while ($row = mysql_fetch_assoc($table)) {
foreach ($row as $key => $value) {
$arr[$key] = $value;
if ($key == "to_data_id") {
$array=mysql_fetch_array(mysql_query("select name,additional from details where data_id=".$value));
$arr["data_id"] = $array['additional'].".".$array['name'];
}
}
$main_arr[] = $arr;
}
}
$data = json_encode($main_arr);
Just how to slow it into this code would be great, thank you! (This code works fine, just want to know what I could change / add to replace those characters).
UPDATE: Is anyone able to give me an answer with how I might be able to use strtr()function to replace the results please? Thanks again for the responses!
In mysql if you manually select a field after selecting * it overwrites that field, so provided there's only one field you want to run replaces on and you know the field you know which field it is in advance you can change your select query to (the somewhat ungraceful):
"select
*,
REPLACE(
REPLACE(
REPLACE(`data`.`YOURFIELDNAME`, '&', 'A'),
',', 'A'),
'\'', 'A')
from
data
where a_data_id=".$ID." AND a_discard_data_from!=1";
Which will remove those characters. This is not very graceful, and as eggyal pointed out, you're better off doing this on the front end.

Search MySQL database with regex substitutions

I want to make a product search engine where the user types in a product code and it will bring back the result, this is easy.
But, I want to be able to compensate for numbers that look like letters and vice versa.
E.g a user types 6O12l, but the product code is actually 60121.
What do I need to put in the SQL query to bring back all products with 6O12l and/or 60121?
So far I have this which isn't working, it keeps bringing back the same result everytime no matter what I type in:
$searchString = $_POST['query'] ;
$searchString = preg_replace('#\W#', '', $searchString);
$firstLetter = substr($searchString, 0, 1) ;
include("db.php") ;
$result = $dbh->prepare("SELECT productCode
FROM products
WHERE productCodeREGEXP '6[O0]12[1l]'
AND productCode LIKE '$firstLetter%'") ;
$result->execute() ;
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
echo $row['productCode'].'<br />' ;
}
I have managed to get it working, but I have encountered a new problem.
I'm using str_replace to substitute the letters for numbers and viceversa in the users query string, but it will only work for one or the other, not both:
$qString = str_replace(array('o', 'l', '0', '1'), array('[O0]', '[1l]', '[O0]', '[1l]'), $searchString) ;
Which gives me a mangled output of e.g. A[[1l]l]BC
Instead of A[1l]BC
Do you have product codes with letters? You can translate the query string to all numbers before you run the query. That's the easiest thing to do, and will be much faster than testing for both.
You can't search the database efficiently with regular expressions. However, you can transform your data for storage in a normalised form, and search using a normalised query string e.g. all O's to zeros, I and l's to ones and so on.
Use this:
SELECT * from products
where code REGEXP '6[O0]12[1l]'
I solved it :D
For reference, I found this function on PHP.net:
function search_replace($s,$r,$sql)
{ $e = '/('.implode('|',array_map('preg_quote', $s)).')/';
$r = array_combine($s,$r);
return preg_replace_callback($e, function($v) use ($s,$r) { return $r[$v[1]]; },$sql);
}
Another option
// regex expresssion
// str_replace goes in order, first change letters to numbers, then change to the regex
// 6012ol becomes 6[0O][1l]2[0O][1l]
$regexString = str_replace(array('o', 'l', '0', '1'), array('0', '1', '[0O]', '[1l]'), $searchString);
// like expression, allows the database to make the initial filter, _ is the single character match
// 6012ol becomes 6__2__
$likeString = str_replace(array('o', 'l', '0', '1'), '_'), $searchString);
$filt1 = "(productCode LIKE '$likeString%')"; // last % allows for partial matches
$filt2 = "(productCode REGEXP '$regexString')";
// now query, with the like filter first
$dbh->prepare("SELECT productCode
FROM products
WHERE $filt1 AND $filt2
") ;

MySQL edit values

Ok, here's an easy one:
I have a table in MySQL where I keep some country names (inserted by the user). The "problem" is that some of the users inserted the country name having no first capital letter.
A need a script (query+PHP) that selects all the values from 1 column inside the table, and apply a PHP script that makes the first letter of every word a capital letter, and the rest in small letter.
Example:
Before edit:
Name oNe
cOUNTRY
VaLue
value
After edit:
Name One
Country
Value
Value
I want to know two things:
->easiest way to edit a value inside a mySQL table
->easiest PHP way to capitalize the first letter of every word (space separated) inside a script
Thanks!
You can use this function:
DELIMITER $$
DROP FUNCTION IF EXISTS `ICap`$$
CREATE FUNCTION `ICap`(mystring varchar(1000))
RETURNS VARCHAR(1000)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE myc, pc CHAR(1);
DECLARE myoutstring VARCHAR(1000) DEFAULT LOWER(mystring);
WHILE i <= CHAR_LENGTH(mystring) DO
SET myc = SUBSTRING(mystring, i, 1);
SET pc = CASE WHEN i = 1 THEN ' ' ELSE SUBSTRING(mystring, i - 1, 1) END;
IF pc IN (' ', '&', '''', '_', '?', ';', ':', '!', ',', '-', '/', '(', '.') THEN
SET myoutstring = INSERT(myoutstring, i, 1, UPPER(myc));
END IF;
SET i = i + 1;
END WHILE;
RETURN myoutstring;
END$$
DELIMITER ;
After that, you can retrieve results like this:
SELECT
ICap(name)
FROM
MyTable
or just update all the rows:
UPDATE
MyTable
SET
name = ICap(name)
To fix the database with only one sql statement use this:
UPDATE country_table SET country_name = CONCAT(UCASE(MID(country_name,1,1)),MID(LOWER(country_name),2));
This will uppercase the first letter of each country name and lowercase the rest. All without needing any PHP at all.
->The easiest way to edit a value inside a mySQL table
UPDATE TABLE SET COL="NEW VALUE" where COL="OLD VALUE";
Be careful, it will replace all line wher COL is equal to OLd VALUE
->easiest PHP way to capitalize the first letter of every word (space separated) inside a script
There's a function for that : http://php.net/manual/en/function.ucwords.php
To Edit the values in in the database just run a Update Query (I don't know how your table is designed) from php -- http://www.w3schools.com/php/php_mysql_intro.asp.
To Capitalize the first character of every word you can use ucwords.
You can do it all in mysql if you want:
SELECT CONCAT(UPPER(SUBSTRING(CountryName, 1, 1)), LOWER(SUBSTRING(CountryName FROM 2))) from countries AS properCountryname;
The resultset returned would be your CountryName field with uppercased first letter.
You coud even do the update in one sql query, if you wanted.
If you really want php to do the job, something like this:
<?php
set_time_limit(0);
$cnt=0;
$con=mysql_connect('localhost','root','');
mysql_select_db('fakeDB',$con);
$query="SELECT `name`,id FROM countries";
$result=mysql_query($query);
while ($row=mysql_fetch_array($result))
{
$name= $row["name"];
$key = $row["id"];
$field = strtolower($name);
$array=explode(" ",$name);
for ($i=0;$i<count($array);$i++)
{
$array[$i] = ucfirst($array[$i]);
}
$field = implode(" ",$array);
$query2 = "UPDATE countries SET `name`='$name' where id=$key";
mysql_query($query2);
$cnt++;
}
echo $cnt." Records updated";
?>
Just a quick untested thingie but it should give you an idea.

Searching Database PHP/MYSQL Question

Right now I'm just using a simple
WHERE name LIKE '%$ser%'
But I'm running into an issue - say the search is Testing 123 and the "name" is Testing, it's not coming back with any results. Know any way to fix it? Am I doing something wrong?
If you want to search for 'Testing' or '123' use OR:
WHERE (name LIKE '%Testing%' OR name LIKE '%123%')
Note however that this will be very slow as no index can be used and it may return some results you didn't want (like "4123"). Depending on your needs, using a full text search or an external database indexing product like Lucene might be a better option.
That's how LIKE works - it returns rows that completely contain the search string, and, if you use "%" optionally contain something else.
If you want to see if the field is contained in a string, you can do it this way:
SELECT * FROM `Table` WHERE "Testing 123" LIKE CONCAT("%",`name`,"%")
As Scott mentioned, you cannot check to see if the search contains the column value, it works the other way round.
so if $ser = "testing" and table has a row name = testing 123 it will return
For what you're trying to do you'll need to tokenize the search query into terms and perform an OR search with each of them or better still check out mysql full text search for a much better approach
After the variable $ser is replaced, the query is:
WHERE name LIKE '%Testing 123%'
You should build the query separating by words:
WHERE name LIKE '%$word[1]%$word[2]%'
not efficient (as your example) but working as you want:
WHERE name LIKE '%$ser%' OR '$ser' LIKE CONCAT('%', name, '%')
As mentioned by Mark and others, a full text search method may be better if possible.
However, you can split the search string on word boundary and use OR logic—but check for the whole string first, then offer the option to widen the search:
NOTE: Input sanitization and preparation not shown.
1. Query with:
$sql_where = "WHERE name LIKE '%$ser%'";
2. If zero results are returned, ask user if they would like to query each word individually.
3. If user requests an 'each word' search, query with:
$sql_where = get_sql_where($ser);
(Working) Example Code Below:
$ser = 'Testing 123';
$msg = '';
function get_sql_where($ser){
global $msg;
$sql_where = '';
$sql_where_or = '';
$ser = preg_replace("/[[:blank:]]+/"," ", trim($ser)); //replace consecutive spaces with single space
$search_words = explode(" ", $ser);
if($search_words[0] == ''){
$msg = 'Search quested was blank.';
}else{
$msg = 'Search results for any of the following words:' . implode(', ', $search_words);
$sql_where = "WHERE name LIKE '%$ser%'";
foreach($search_words as $word){
$sql_where_or .= " OR name LIKE '%$word%'";
}
}
return $sql_where . $sql_where_or;
}
$sql_where = get_sql_where($ser);
//Run query using $sql_where string

Categories