how to split a string into substring using php [duplicate] - php

This question already has answers here:
How can I bind an array of strings with a mysqli prepared statement?
(7 answers)
Closed 6 months ago.
I have a string like this 'dubai,sharjah,' and I want to make it like this 'dubai','sharja',
I am passing the value dubai,sharjah, in the URL using ajax and my code
$city=$_GET['city'];
$sql = "SELECT * FROM filter where isdeleted = 0 ";
if ($city !="" && $city !="Empty" ){
$sql.=" and twon in ('".$citydata."')";
}
when I print the query, it's like this
SELECT * FROM filter where isdeleted = 0 and twon in ('dubai,sharjah,')
but I want it like this
SELECT * FROM filter where isdeleted = 0 and twon in ('dubai','sharja')
Can anyone guide me on how to do this using PHP?

Here's how I would approach it. I'm going to use PDO instead of mysqli because trying to get an array into mysqli_stmt::bind_param is just a pain.
First, create an array of cities, removing any empty values
$params = array_filter(explode(',', $city), function($c) {
return !empty($c) && $c !== 'Empty';
});
$paramCount = count($params);
$query = 'SELECT * FROM filter where isdeleted = 0';
Now generate a placeholder string for your prepared statement.
if ($paramCount) {
$placeholders = implode(',', array_fill(0, $paramCount, '?');
// looks something like '?,?'
$query .= " AND twon IN ($placeholders)";
}
Now, prepare a statement
// assuming you have a PDO instance in $pdo created with something like
// $pdo = new PDO('mysql:host=localhost;dbname=your_db;charset=utf8', 'username', 'password', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$stmt = $pdo->prepare($query);
Execute and fetch values :)
$stmt->execute($params);
$filters = $stmt->fetchAll(PDO::FETCH_ASSOC);

$cities = explode(",", $_GET['city']);
//escape!
foreach ($cities as $citykey => $city) {
$cities[$citykey] = "'" . mysql_real_escape_string($city) . "'";
}
$sql = "SELECT * FROM `filter` where `isdeleted` = 0";
if (!empty($cities)) {
$sql .= ' and `twon` in (' . implode(',', $cities) . ')';
}

An alternative is to use FIND_IN_SET(). No PHP code change needed.
$sql.=" and FIND_IN_SET(town, '".$citydata."')";

you can try to explode the string
$cityparts = explode(",",$city);
and you can use
$cityparts[0] and $cityparts[1] in your query
array explode ( string $delimiter , string $string [, int $limit ] )
you can find more information on [http://www.php.net/explode]
hope this helps!!

You just have to explode and implode here. Rest is the problem with extra , in your string at the end.
$str = "dubai,sharjah,";
$citydata = implode("','",explode(',',rtrim($str,',')));
echo "'$citydata'";
test

After 6 answers I gotta add a 7th:
$sql.=" and twon in ('".str_replace(",","','",$citydata)."')";

You can do this.
$string = 'dubai,sharjah';
$cities = explode(',', $string);
echo $cities[0]; //dubai
echo $cities[1]; //sharjah

try this
$str = "dubai,sharjah,";
$arr = explode(",", $str);
$arr_temp = array()
foreach($arr as $s)
{
if($s!="")
{
$arr_temp[] = "'".$s."'";
}
}
$new_str = implode(",", $arr_temp);
echo $new_str; // output 'dubai','sharjah'
Now your Sql will be
$sql = "SELECT * FROM filter where isdeleted = 0 and twon in ($new_str) ";

You can use it
in $city I fix two values with, you can use here by $_GET ;
$city = "dubai,sharjah,";
$query_string ="";
$words = explode(",",$city);
for($i=0;$i<count($words);$i++){$query_string .= "'".$words[$i]."',";}
$query_string = substr($query_string,0,strlen($query_string)-4);
then use your query
SELECT * FROM filter where isdeleted = 0 and twon in ($query_string)

if ($city !="" && $city !="Empty" )
{
$city_exp = explode(',' $city);
$sql .= " and twon in ('".implode("', '", $city_exp)."')";
}
What we are basically doing here is putting the two values in an array by using explode and then separating each item in that array by using implode
DEMO

Related

How to pass a php array to a postgres query with any condition

i wrote the following code:
<?php
$listO = $_POST["letter"];
//print_r($listO);
//Array ( [0] => A [1] => B [2] => C)
function to_pg_array($set) {
settype($set, 'array'); // can be called with a scalar or array
$result = array();
foreach ($set as $t) {
if (is_array($t)) {
$result[] = to_pg_array($t);
} else {
$t = str_replace('"', '\\"', $t); // escape double quote
if (! is_numeric($t)) // quote only non-numeric values
$t = '"' . $t . '"';
$result[] = $t;
}
}
return '{' . implode(",", $result) . '}'; // format
}
$pg_array_listO = to_pg_array($listO);
//print_r($pg_array_list_organisms);
//{"A","B","C"}
$conn = pg_connect("host=X dbname=Y user=Z");
$result = pg_query_params($conn, 'SELECT count(cp.id)
FROM cp, act, a, t
WHERE t.tid = a.tid AND
a.aid = act.aid AND
act.m = cp.m AND
t.n = $1 AND
act.st = $2 AND
t.o LIKE ANY(ARRAY[$3])', array($t1, $a2, $pg_array_listO));
while($row = pg_fetch_row($result)) {echo $row[0];}
?>
However i can't figure out how to pass the array $pg_array_listO to the postgres query. The function to_pg_array converts the php array into postgres array but still don't work. How can i do this?
postgres array looks like '{list}' :
t=# select array['a','b','c'];
array
---------
{a,b,c}
(1 row)
so you need to get rid of double quotes, otherwise postgres understands literals as identities.
Eg with $pg_array_listO = str_replace('"', '\\"',to_pg_array($listO)) or smth smarter - sorry - I'm not good in php
additionally modify ANY(ARRAY[$3]) to ANY('$3'::text[]), cos array[] or '{}'::text[] would be accepted
update
based on
//print_r($pg_array_list_organisms);
//{"A","B","C"}
I expect this to work:
$result = pg_query_params($conn, "SELECT count(cp.id)
FROM cp, act, a, t
WHERE t.tid = a.tid AND
a.aid = act.aid AND
act.m = cp.m AND
t.n = $1 AND
act.st = $2 AND
t.o LIKE ANY($3)", array($t1, $a2, str_replace('"', '',to_pg_array($listO))));
mind I changed quotes and SQL and str_replace for $3 variable
a working example of this approach:
t=# select 'a' like any('{a,b,c}'::text[]);
?column?
----------
t
(1 row)

PHP Array to string conversion, mysql_fetch_assoc() expects parameter [duplicate]

This question already has answers here:
mysql_fetch_array()/mysql_fetch_assoc()/mysql_fetch_row()/mysql_num_rows etc... expects parameter 1 to be resource
(31 answers)
Closed 8 years ago.
Can someone please help me with my code, I can't get it to work.
I have an html input form where I type for example "This is a sample".
(data is saved in $_POST['Begriff'])
I want to achive a simple translation, so that the table "drinks" in column "English" is checked for existence of every single word from my input sample sentence and output if found every entry from the corresponding row in one line.
Right now I have two problems:
As soon as I add " where English in $wert" to the select statement I get:
Notice: Array to string conversion in nachlesen.php on line 34
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given
Second Problem: How to I put the sentence together again from the returned results?
(Right now I get the output for every found word below each other, instead of one line)
Here is my code:
if ( $_POST['Begriff'] <> "")
{
$wert = explode(' ',$_POST['Begriff']);
$select = mysql_query ("SELECT * FROM drinks where English in $wert");
while ( $row = mysql_fetch_assoc($select))
{
echo ("$row[German] <br>");
echo ("$row[English]<br>");
}
}
Thanks in Advance, Daniel
<?php
// premise: the user input in $_POST['Begriff'] is a string like 'This is a sample'
//first split it into single words
// preg_split: \s+ -> one or more whitespaces , PREG_SPLIT_NO_EMPTY -> no "empty" words
// e.g. " Mary had a little lamb" -> array('Mary','had','a','little','lamb')
$words = preg_split('!\s+!', $_POST['Begriff'], -1, PREG_SPLIT_NO_EMPTY);
// now encode each string so that it can be used
// safely as a string-literal within your sql query
// see: sql injection
// this should be:
// $words = array_map(function($e) use($mysql) { return mysql_real_escape_string($e, $mysql); }, $words);
// but apparently you're not storing the resource that is returned by mysql_connect
// mysql_real_escape_string() is applied to each single element in $words
// e.g. array("it's", "been") -> array("it\\'s", "been")
$words = array_map('mysql_real_escape_string', $words);
// now put the string literals into your query
// format: ... IN ('x','y','z')
// join(",", $words) gives you x,y,z
// join("','", $words) gives you x','y','z
// i.e. the first and the last ' has to be added "manually"
// keep in mind that for an empty array $words this will produce WHERE ... IN ('')
// better test that before even trying to build the query
$query = sprintf("
SELECT
German,English
FROM
drinks
WHERE
English IN ('%s')
", join("','", $words));
// send the query to the MySQL server
// should be: $result = mysql_query($query, $mysql);
$result = mysql_query($query);
// database query -> failure is always an option
if ( !$result ) {
// add error handling here
}
else {
// in case there is not a single match in the database
// your script would print ...nothing
// I don't like that - but that debatable
// anway: wrapped in a fieldset
echo '<fieldset><legend>results:</legends>';
while( false!==($row=mysql_fetch_array($result, MYSQL_FETCH_ASSOC)) ) {
printf('%s<br />%s<br />',
// just like on the input-side you had to worry about
// sql injections
// on the output side you want to avoid
// that characters from the database can break your html structure
htmlentities($row['German']),
htmlentities($row['English'])
);
}
echo '</fieldset>';
}
(script is untested)
why don't you try implode() and convert your array to string??
if ( $_POST['Begriff'] <> "")
{
//you'l have to replace all "spaces with ',' "
$pattern = '/\s*,\s*/';
$replace = "','";
$wert = preg_replace($pattern, $replace, $_POST['Begriff']);
$select = mysql_query ("SELECT * FROM drinks where English in ('$wert')");
while ( $row = mysql_fetch_assoc($select))
{
echo ("$row[German] <br>");
echo ("$row[English]<br>");
}
}
ANOTHER SOLUTION (TO PREVENT SQL INJECTION)
if ( $_POST['Begriff'] <> "")
{
//replace multiple spaces
$str1 = preg_replace( "/\s+/", " ", $_POST['Begriff'] );
//convert to array, separated by space
$arr=explode(" ",$str1);
$safe_params=array();
foreach($arr as $param){
$safe_params[]=mysql_real_escape_string($param);
}
$wert=implode("','",$safe_params);
$select = mysql_query ("SELECT * FROM drinks where English in ('$wert')");
while ( $row = mysql_fetch_assoc($select))
{
echo ("$row[German] <br>");
echo ("$row[English]<br>");
}
}
EDIT
Processing query output according to language
$german_words=array();
while ( $row = mysql_fetch_assoc($select))
{
$german_words[$row['English']]=$row['Gernam'];
}
//$str1 is having english string
echo "English: ".$str1."<br/>";
echo "German : ";
//$arr is having array of words of $str1
foreach($arr as $eng_word){
echo $german_words[$eng_word]." ";
}
"SELECT * FROM drinks where English in ('". implode("','", $wert) . "')"
EDIT: SQL Injection safe query:
$dsn = 'mysql:dbname=' . $settings['dbname'] . ';host=' . $settings['dbhost'];
$pdo = new PDO($dsn, $settings['dbuser'], $settings['dbpass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
if ( $_POST['Begriff'] <> "")
{
$wert = explode(' ',$_POST['Begriff']);
$placeholders = implode(',', array_fill(0, count($wert), '?'));
$sth = $pdo->prepare("SELECT * FROM drinks WHERE English in ({$placeholders})");
$sth->execute($wert);
$rows = $sth->fetchAll();
foreach($rows as $row) {
print_r( $row );
}
}

PHP -> PDO Update Function using Foreach array merge

The following code is supposed to check for the column names of a table. Then check to see if a corresponding variable has been $_POST and if it has add it to the $SQL. I believe there is a problem with the array that contains a series of arrays but I don't know how to dix it.
$where = $_POST['where'];
$is = $_POST['is'];
$table = $_POST['table'];
$sql = "UPDATE $table SET";
$array = array();
$columnnames = columnnames('blog');
foreach ($columnnames as $columnname){
if($_POST[$columnname]){
$sql .= " $columnname = :$columnname,";
$array .= array(':$columnname' => $_POST[$columnname],);
}
}
$sql = rtrim($sql,',');
$array = rtrim($array,',');
$sql .= " WHERE $where = '$is'";
$q = $rikdb->prepare($sql);
$q->execute($array);
For the sake of comprehension please except that $columnnames = columnnames('blog'); works as it does.
Change this:
$array .= array(':$columnname' => $_POST[$columnname],);
to this:
$array[':$columnname'] = $_POST[$columnname];
and after that use rtrim only on $sql.
the problem is here $array .= array(':$columnname' => $_POST[$columnname],);
you have a , part of the value which is not literal. change it to be like
$array .= array(':$columnname' => $_POST[$columnname] . ",");
You can also add your column names and values to an array and implode(",", $array) so you don't have to use rtrim
Instead of using
$array .= array(':$columnname' => $_POST[$columnname],);
and applying rtrim on results, I'd suggest the easier and failsafe method:
$array[':$columnname'] = $_POST[$columnname];

How would I sort this array [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to sort the results of this code?
Im making a search feature which allows a user to search a question and it will show the top 5 best matching results by counting the number of matching words in the question.
Basically I want the order to show the best match first which would be the question with the highest amount of matching words.
Here is the code I have.
<?php
include("config.php");
$search_term = filter_var($_GET["s"], FILTER_SANITIZE_STRING); //User enetered data
$search_term = str_replace ("?", "", $search_term); //remove any question marks from string
$search_count = str_word_count($search_term); //count words of string entered by user
$array = explode(" ", $search_term); //Seperate user enterd data
foreach ($array as $key=>$word) {
$array[$key] = " title LIKE '%".$word."%' "; //creates condition for MySQL query
}
$q = "SELECT * FROM posts WHERE " . implode(' OR ', $array); //Query to select data with word matches
$r = mysql_query($q);
$count = 0; //counter to limit results shown
while($row = mysql_fetch_assoc($r)){
$thetitle = $row['title']; //result from query
$thetitle = str_replace ("?", "", $thetitle); //remove any question marks from string
$title_array[] = $thetitle; //creating array for query results
$newarray = explode(" ", $search_term); //Seperate user enterd data again
foreach($title_array as $key => $value) {
$thenewarray = explode(" ", $value); //Seperate each result from query
$wordmatch = array_diff_key($thenewarray, array_flip($newarray));
$result = array_intersect($newarray, $wordmatch);
$matchingwords = count($result); //Count the number of matching words from
//user entered data and the database query
}
if(mysql_num_rows($r)==0)//no result found
{
echo "<div id='search-status'>No result found!</div>";
}
else //result found
{
echo "<ul>";
$title = $row['title'];
$percentage = '.5'; //percentage to take of search word count
$percent = $search_count - ($search_count * $percentage); //take percentage off word count
if ($matchingwords >= $percent){
$finalarray = array($title => $matchingwords);
foreach( $finalarray as $thetitle=>$countmatch ){
?>
<li><?php echo $thetitle ?><i> <br />No. of matching words: <?php echo $countmatch; ?></i></li>
<?php
}
$count++;
if ($count == 5) {break;
}
}else{
}
}
echo "</ul>";
}
?>
When you search something it will show something like this.
Iv put the number of matching words under each of the questions however they are not in order. It just shows the first 5 questions from the database that have a 50% word match. I want it to show the top 5 with the most amount of matching words.
What code would I need to add and where would I put it in order to do this?
Thanks
Here's my take on your problem. A lot of things have been changed:
mysql_ functions replaced with PDO
usage of anonymous functions means PHP 5.3 is required
main logic has been restructured (it's really hard to follow your result processing, so I might be missing something you need, for example the point of that $percentage)
I realize this might look complicated, but I think that the sooner you learn modern practices (PDO, anonymous functions), the better off you will be.
<?php
/**
* #param string $search_term word or space-separated list of words to search for
* #param int $count
* #return stdClass[] array of matching row objects
*/
function find_matches($search_term, $count = 5) {
$search_term = str_replace("?", "", $search_term);
$search_term = trim($search_term);
if(!strlen($search_term)) {
return array();
}
$search_terms = explode(" ", $search_term);
// build query with bind variables to avoid sql injection
$params = array();
$clauses = array();
foreach ($search_terms as $key => $word) {
$ident = ":choice" . intval($key);
$clause = "`title` LIKE {$ident}";
$clauses []= $clause;
$params [$ident] = '%' . $word . '%';
}
// execute query
$pdo = new PDO('connection_string');
$q = "SELECT * FROM `posts` WHERE " . implode(' OR ', $clauses);
$query = $pdo->prepare($q);
$query->execute($params);
$rows = $query->fetchAll(PDO::FETCH_OBJ);
// for each row, count matches
foreach($rows as $row) {
$the_title = $row->title;
$the_title = str_replace("?", "", $the_title);
$title_terms = explode(" ", $the_title);
$result = array_intersect($search_terms, $title_terms);
$row->matchcount = count($result);
}
// sort all rows by match count descending, rows with more matches come first
usort($rows, function($row1, $row2) {
return - ($row1->matchcount - $row2->matchcount);
});
return array_slice($rows, 0, $count);
}
?>
<?php
$search_term = filter_var($_GET["s"], FILTER_SANITIZE_STRING);
$best_matches = find_matches($search_term, 5);
?>
<?php if(count($best_matches)): ?>
<ul>
<?php foreach($best_matches as $match): ?>
<li><?php echo htmlspecialchars($match->title); ?><i> <br/>No. of matching words: <?php echo $match->matchcount; ?></i></li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<div id="search-status">No result found!</div>
<?php endif; ?>
Try adding asort($finalarray); after your $finalarray = array($title => $matchingwords); declaration:
...
if ($matchingwords >= $percent){
$finalarray = array($title => $matchingwords);
asort($finalarray);
....
It should sort your array Ascending by the Values

multiple terms SQL with explode/implode and PHP PDO

I have a search form that would like the users to search multiple terms. I'm currently using PHP PDO and I'm still learning... I was wondering if someone can tell me what I'm doing wrong here.
$varSearch = #$_GET['dms'];
$varTerm = explode(" ", $varSearch);
$termArray = array();
foreach($varTerm as $term){
$term = trim($term);
if(!empty($term)){
$termArray[] = "name LIKE '%".$term."%' OR tags LIKE '%".$term."%'";
}
}
$implode = implode(' OR ', $termArray);
$sql = $dbh->prepare("SELECT * FROM table WHERE ?");
$sql->execute(array($implode));
Have you considered doing something like this, instead:
$varSearch = #$_GET['dms'];
$varTerm = explode(" ", $varSearch);
$termsStringArray = array();
$termsArray = array();
foreach($varTerm as $term){
$term = trim($term);
if(!empty($term)) {
array_push($termsStringArray, "name LIKE ? OR tags LIKE ? ");
array_push($termsArray, $term);
array_push($termsArray, $term); // note, you can do this part differently, if you'd like
}
}
$implodedTermsString = implode('OR ', $termsStringArray);
$sql = $dbh->prepare("SELECT * FROM biz WHERE " . $implodedTermsString);
$sql->execute(array($termsArray));
Output:
// prepare statement
SELECT * FROM biz WHERE name LIKE ? OR tags LIKE ? OR name LIKE ? OR tags LIKE ? OR name LIKE ? OR tags LIKE ? OR name LIKE ? OR tags LIKE ?
// $termsArray (for execute)
Array
(
[0] => this
[1] => this
[2] => is
[3] => is
[4] => the
[5] => the
[6] => string
[7] => string
)
Basically, trying to separate the array data from the initial SQL query prepare string. Let me know if that works for you!
Though, you still will want to do some sort of checking (or sanitization,) of the data you are getting from the $_GET variable. That $_GET variable could have anything in it... and could be bad for SQL injections or other unwanted issues.
And, LIKE isn't necessarily going to be the most efficient way to do this type of database search. But if you use it (and I have used it for search things in the past,) try checking out: http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning.
If anyone else needs this answer too...
$varSearch = #$_GET['dms'];
$varTerm = explode(" ", $varSearch);
$termArray = array();
foreach($varTerm as $term){
$term = trim($term);
if(!empty($term)){
$termArray[] = "name LIKE :term OR tags LIKE :term";
}
}
$implode = implode(' OR ', $termArray);
$sql = $dbh->prepare("SELECT * FROM table WHERE ".$implode."");
$sql->execute(array(":term"=>"%".$term."%"));
Remake
$my_explode = explode(" ",$search);
$query = array();
foreach($my_explode as $string)
{
$query[] ="name LIKE '%".$string."%' OR email LIKE '%".$string."%'";
}
$implode = implode(' OR ', $query);
foreach ($db->query("SELECT * FROM _table WHERE ".$implode."") as $info)
{
echo $info['name']."<br />";
}
Secure for injection, with php retrieve just alphanumeric chars
$search = preg_replace("/[^a-zA-Z0-9]+/", "-", $_GET["text"]);

Categories