MySQL Query Into Array for preg_replace - php

ORIGINAL CODE
$sentance="are you hungry too?";
function newLanguage($text) {
$sql = "SELECT in,out FROM words";
$res = mysql_query($sql) or die();
$in_array = array();
$out_array = array();
while ($row = mysql_fetch_array($res)){
$in_array[] = $row['in']; // table in, NEW words
$out_array[] = $row['out']; //table out, ENG words
}
return preg_replace($in_array,$out_array,$text);
}
$newwords = newLanguage($sentance);
echo $newwords;
AMENDED CODE:
ini_set("display_errors", "1");
error_reporting(E_ALL);
function newLanguage($text) {
$sql = "SELECT in,out FROM words";
$res = mysql_query($sql) or die();
$in_array = array();
$out_array = array();
while ($row = mysql_fetch_array($res)){
$in_array[] = '/\b' . preg_quote($row['in']) . '\b/'; // table in, NEW words
$out_array[] = $row['out']; //table out, ENG words
}
/* VERSION 2 - STATIC, FOR DEBUGGING
$in_array = array('~\you~s','~\to~s','~\too~s');
$out_array = array('noa','nie','niee');*/
return preg_replace($in_array,$out_array,$text);
}
$sentance="are you hungry too?";
$newwords = newLanguage($sentance);
var_dump($in_array);
echo $sentance;
CURRENT CODE
ini_set("display_errors", "1");
error_reporting(E_ALL);
$sentance="are you hungry too?";
function newLanguage($text) {
$sql = "SELECT * FROM words";
$res = mysql_query($sql) or die();
while ($row = mysql_fetch_array($res)){
$in_array[] = '/\b' . preg_quote($row['in']) . '\b/'; // table in, NEW words
$out_array[] = $row['out']; //table out, ENG words
}
return preg_replace($in_array,$out_array,$text);
}
$newwords = newLanguage($sentance);
var_dump($in_array);
echo $newwords;
I'm having Problems with my code, for the life of me I cannot get it to work, I have worked with preg_replace before in using a word filter. Though creating a dynamic array using query results totally throws me off. I have looked at a few tutorials but none have really helped me understand where I am going wrong.
Any help would be grateful :)
GOAL:
Creating a New Language translation. Database holds a row with 'in' & 'out' which is both the new language and local language.
PROBLEM:
I'm unsure if my Arrays are being successfully populated since my preg_replace isn't working.
----UPDATE----
Here is what my database looks like;
id in out
1 you noa
2 to nie
3 too niee
They are stored as VARCHARS

Try this:
while ($row = mysql_fetch_array($res)){
$in_array[] = '/\b' . preg_quote($row['in']) . '\b/'; // table in, NEW words
$out_array[] = $row['out']; //table out, ENG words
}
This turns the in worods into regular expressions, adding \b to match word boundaries.
My whole test code is:
<?php
$sentance="are you hungry too?";
function newLanguage($text) {
$in_array = array();
$out_array = array();
$rows = array(array('in' => 'you', 'out' => 'noa'),
array('in' => 'to', 'out' => 'nie'),
array('in' => 'too', 'out' => 'niee'));
foreach ($rows as $row) {
$in_array[] = '/\b' . preg_quote($row['in']) . '\b/'; // table in, NEW words
$out_array[] = $row['out']; //table out, ENG words
}
return preg_replace($in_array,$out_array,$text);
}
$newwords = newLanguage($sentance);
echo $newwords;
The $rows array replaces the database query, but the rest is essentially the same.

BIG thank you to Barmar for his dedicated help and patience in helping me solve my question!
I have made his answer correct since he helped me so much but if you wish to use my final code that is commented please feel free.
My Goal was to IMPORT database rows and insert them into an Array which will be used with preg_replace.
My Final Code was:
//this is the base text that will be modified using database information
$sentance="are you hungry too?";
function newLanguage($text) {
$sql = "SELECT * FROM words";
$res = mysql_query($sql) or die();
$in_array = array();
$out_array = array();
while ($row = mysql_fetch_array($res)){
// inserts the column row 'in' into an array called in_array
$in_array[] = '/\b' . preg_quote($row['in']) . '\b/';
// inserts the column row 'out' into an array called out_array
$out_array[] = $row['out'];
}
//replaced any matching words from 'sentance' with 'in_array' and replaces with 'out_array'
return preg_replace($in_array,$out_array,$text);
}
//this makes a new variable and used a function to replace the text with matches in the variable
$newwords = newLanguage($sentance);
echo $newwords;

Related

select where id in csv string - how to do something if row is missing

I have a csv string and need to select rows having corresponding id.
And need to do something specific if a row doesn't exist.
$str = '1,2,3,4,5,6,7,8,9,10,11,12';
$st = $db->query("select *
from arts
where id in (" . $str . ")
order by field (id, " . $str . ")");
$arr = $st->fetchAll(PDO::FETCH_ASSOC);
foreach ($arr as $el) {
// if ($el is missing) {echo 'the row is missing';} // how to do this?
else { ... }
}
The easiest option here, assuming you are stuck with the input CSV string, is to use FIND_IN_SET, something along these lines:
$sql = "SELECT id, FIND_IN_SET(id, :list) AS result FROM arts";
$str = "1,2,3,4,5,6,7,8,9,10,11,12";
$stmt = $db->prepare($sql);
$stmt->bindParam(':list', $str);
$stmt->execute();
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($arr as $el){
if ($el["result"] <= 0) {
echo "the row is missing for id " . $el["id"];
}
}
Rather than look at the records found, this code first keys the retrieved records on the id and then looks through the ID's you are looking for and if this record isn't found (using isset()) then process the not found part...
$arr = array_column($arr, null, "id");
$ids = explode(",", $str);
foreach($ids as $el){
if(!isset($arr[$el])) {
echo 'the row is missing';
} else{
echo 'the row is there';
}
}

How to find a database row that matches a string?

I have a databse table with 100K rows and an array of 100 items. And I need to find if an array item is found in my Users table username row.
My database table Users
| id | username | fullname |
1 John John Smith
2 Elliot Jim Elliot
3 Max Max Richard
My array looks like this
[
{
string: 'Hello, this is Elliot from downtown Las Vegas!'
},
{
string: 'Hey how are you?'
}
]
My idea was to do a foreach loop through every row in my Users table (100k records) and find if it matches in my array, but it is so slow.
foreach ($MyArray as $Array) {
foreach ($dbrows as $dbrow) {
if (strpos($Array['string'], $dbrow['username']) !== false) {
echo 'found it!';
break;
}
}
}
It will be a bit hit and miss as you may find users with all sorts of weird names that match normal words, this approach splits the input into words and then uses them to form an in clause to search the database. So it only looks at records that match rather than all records...
$search = 'Hello, this is Elliot from downtown Las a1 Vegas!';
$words = str_word_count($search, 1);
$bind = str_repeat("?,", count($words));
$bind = trim($bind, ",");
$query = $conn->prepare("select * from users where username in ($bind)" );
$types = str_repeat("s", count($words));
$query->bind_param($types, ...$words);
$query->execute();
$res = $query->get_result();
while($row = $res->fetch_assoc()) {
// Process result
}
It also uses prepared statements, which is where all of the $bind and $types processing comes in. If you look at $query you will see how it's built up.
I think the better way was to separate your search arrays into words, and use it in the query, like:
<?php
// Assuming your search array is $search...
$words = array ();
foreach ( $search as $text)
{
$words = array_merge ( $words, explode ( " ", trim ( preg_replace ( "/[^0-9a-z]+/i", " ", $text))));
}
$words = array_unique ( $words);
$in = "";
foreach ( $words as $text)
{
$in .= ",'" . $mysqli->real_escape_string ( $text) . "'";
}
if ( ! $result = $mysqli->query ( "SELECT * FROM `Users` WHERE `username` IN (" . substr ( $in, 1) . ")"))
{
echo "MySQL error!";
}
// Results at $result
?>
You can use regular expressions:
<?php
$query_string = "bla bla bla...";
$qry = $mysqli_query($conn, "SELECT *FROM table WHERE username REGEXP '$query_string'");
?>
Regular expression matches data individually from table.

search array of words in database

I have text :
$a = I wanna eat apple , and banana .
I wanna get every words and punctuation of that sentence :
$b = explode(' ', strtolower(trim($a)));
the result of explode is array.
I have a words table on db that has fields : id, word and typewords all in lowercase. but for punctuation there are no exist in db.
I wanna search every words in db to take the type of words, so the final result that i want to get is :
words/typeofwords = I/n wanna/v eat/v apple/n ,/, and/p banana/n ./.
here's the code :
function getWord ($word){
$i = 0 ;
$query = mysql_query("SELECT typewords FROM words WHERE word = '$word' ");
while ($row = mysql_fetch_array($query)) {
$word[$i] = $row['typewords'];
$i++;
}
return $word;
}
echo $b.'/'.getWord($b);
but it doesn't work, please help me, thanks !
Try with this:
function getWord($words){
$association = array();
foreach($words as $word)
{
$query = mysql_query("SELECT typewords FROM words WHERE word = '$word' ");
if($row = mysql_fetch_array($query))
$association[$word] = $row['typewords'];
elseif(preg_match('/[\.\,\:\;\?\!]/',$word)==1)
$association[$word] = $word;
}
return $association;
}
$typewords = getWord($b);
foreach($b as $w)
echo $w.'/'.$typewords[$w];
function getWord($word){
// concat the word your searching for with the result
// http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat
$query = mysql_query("SELECT CONCAT(word,'/',typewords) as this_result FROM words WHERE word = '$word' ");
$row = mysql_fetch_array($query);
return $row['this_result']." "; // added a space at the end.
}
// loop through the $b array and send each to the function
foreach($b as $searchword) {
echo getWord($searchword);
}
You assume the function parameter to be an array, but it is a string.
Edit: In your function you treat $word as an array as well as a string. Decide what you want and recode your function.

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

Remove last comma or prevent it from being printed at all MySQL/PHP

I am printing a set of words that is placed in a MySQL database and I am retrieving it with PHP. I want to present it as a comma separated list, but I need it not to print or remove the last comma. How could I do this?
I did try to use rtrim, but I did not probably do it right.
This is my code as it is today:
<?php
$query0 = "SELECT LCASE(ord) FROM `keywords` ORDER BY RAND()";
$result0 = mysql_query($query0);
while($row0 = mysql_fetch_array($result0, MYSQL_ASSOC))
{
$keyword = $row0['LCASE(ord)'];
echo "$keyword, ";
?>
I did try to use rtrim, my attempt was something like this (I might be honest enough to say that I am in above my head in this ;) )
$keyword = $row0['LCASE(ord)'];
$keywordc = "$keyword, ";
$keyword- = rtrim($keywordc, ', ');
echo "$keyword-, ";
As you might imagine, this did not print much (but at least it did not leave me with a blank page...)
I would do:
$keywords = array();
while($row0 = mysql_fetch_array($result0, MYSQL_ASSOC))
{
$keywords[] = $row0['LCASE(ord)'];
}
echo implode(',', $keywords);
I usually do this by placing the results in an array first
$some_array = array();
while($row0 = mysql_fetch_array($result0, MYSQL_ASSOC)) {
$some_array[] = $row0['LCASE(ord)'];
}
then simply:
echo "My List: " . implode(', ', $some_array);
// Output looks something like:
My List: ord1, ord2, ord3, ord4
substr($string, 0, -1);
That removes the last character.

Categories