This is really a dumb question from a beginner, I have a table called "stations" inside my database and on it I have a column called "keywords".
I need to retrieve all those rows that contain one specific keyword (let's say "pizza").
I tried with this but it didn't work:
foreach ($stations->result() as $row)
{
foreach ($row->keywords as 'pizza')
{
<--my code-->
}
}
How could I retrieve all rows that contain "pizza" inside a specific column using PHP?
You can accomplish this using explode() to turn the list into an array. Then you can use in_array():
foreach ($stations->result() as $row) {
if ( in_array('pizza', explode(",", $row->keywords) ) ) {
<--my code-->
}
}
explode(",", $row->keywords) turns your comma-separated list into an array.
in_array('pizza', $array ) returns TRUE if pizza is found, otherwise it returns FALSE.
Instead of parsing it in PHP, you can select only the relevant rows using find_in_set:
SELECT *
FROM stations
WHERE FIND_IN_SET ('pizza', keywords) > 0
Related
With the updated code below, my search is working, but only using the last word in the Array. Is there a way to search the MySQL column using all words the user inputted?
Note: All input sanitization and escaping is completed in my code but not shown here.
I have two PHP arrays: $search_exploded (user inputted search terms) and $metaphoneArr (metaphones of keywords in MySQL).
I'm cycling through $search_exploded and $metaphoneArr, and if the Levenshtein is less than 2, then I'm adding the metaphone element to a third array called $levenResultsArr.
In MySQL, I'm joining two tables, and if there's a result in my third array ($levenResultsArr) that matches a row in my metaphone_col, then I want the results printed. Somehow, though, I am not referencing the third array correctly in the MySQL statement.
Any advice? Here is part of my PHP code.
$levenResultsArr = array();
foreach ($search_exploded as $search_each => $searchWord) {
$search_each2 = metaphone($searchWord);
echo $search_each2 . "<br/>";
foreach ($metaphoneArr as $metaword => $val) {
$lev = levenshtein($search_each2, $val);
if ($lev < 2) {
array_push($levenResultsArr, $search_each2);
}
}
}
// And shown below is the MySQL statement
$constructs = "
SELECT vt.idvideolist,
vt.videotitle,
vt.videodescription
FROM videolist_tbl vt
INNER JOIN keyword__video k2v ON (vt.idvideolist = k2v.video_id)
INNER JOIN keywords_tbl k ON (k2v.keyword_id = k.idkeywords_tbl)
WHERE k.metaphone_col = '$search_each2'
";
It's only searching using the last word in the array instead of all words in the array.
You're correct that you aren't referencing your array correctly in your query. You are simply referencing the variable '$search_each2'. You want to check the entire array. The best way to do this would to be to convert the array to a string using implode and using the MySQL IN clause. We need to modify the array first to format it correctly:
foreach($levenResultsArr as &$foo){
$foo = "'".$foo."'"; //add single quotes around each object in the array
}
$levenAsStr = implode(",", $levenResultsArr);
Then simply change your last line to the following:
WHERE k.metaphone_col IN (".$levenAsStr.")";
Did this from memory because I'm not in a testing environment, please let me know if there are any syntax errors. Should work for you!
Without seeing more of the code its a bit difficult to determine what is going on. A couple of thoughts though.
What var is the array containing all search terms?
I noticed you are pushing items into $levenResultsArr. I don't see it being used in the query though.
If it is $search_each_2 you may try using the IN syntax:
WHERE k.metaphone_col IN '$search_each2';
This will only match exact values however. i.e.:
some value does not return if the IN array contains value. The array would have to contain some value
If you need it to match partial searches you may try using LIKE with wildcards: %
WHERE k.metaphone_col LIKE "%searchTerm1%"
OR k.metaphone_col LIKE "%searchTerm2%"
OR k.metaphone_col LIKE "%searchTerm3%"
You could potentially use the implode function to create the sql string from the array: http://php.net/manual/en/function.implode.php
Suppose I have an SQL Statement that looks like:
SELECT * FROM myTable;
Now back in PHP I have a result array $result[], How can I iterate through that array and print out the values if I don't know the column names? Can I interrogate the array somehow?
Background: I have a table, I've rendered the table headings based on the a metadata table, now I need to populate the data, but I only want to pull out the field names that match the table headers and insert them into the HTML Table.
This process is happening dynamically, every table is different and has different field names (discovered by interrogating the metadata), but shares the same php code, so it needs to be flexible and smart enough to figure out what to render.
Edit: I now understand that your $result is an array of arrays.
foreach ($result as $row) {
foreach ($row as $key => $value) {
print "column $key has value $value\n";
}
}
Or you can call array_keys($row) to return the keys of an associative array.
You can use foreach loop with key-value pair in that case.
You can use it like this,
foreach($result as $key=>$value) {
//$key returns the key of $result array
//$value returns the respective value of that key
}
We have a nasty database call using the Wordpress function $wpdb->get_results(SQL).
After receiving the result in PHP, we need to make a few changes to the result.
So can anyone tell me how I can:
1) Remove specific rows from the get_results() returned object.
2) Change the values of the specific columns in specific rows in the returned object.
I.e. if the object returned is $nastyData, we need to:
1) Remove specific rows from $nastyData
2) Change the value of specific columns in specific rows in $nastyData, for example $nastyData->name for a specific row.
Any ideas?
I have thought about makeing get_results() return the data as an array, but that will create problems in other places in our code (where the code expects to receive an object).
Thanks,
Mads
To start with, your "Nasty database call" should be optimized to be less nasty. More specifically, only query the results you want so that you don't have to remove stuff afterwords. This is the best solution.
If you insist on trying to modify the objects, this is a workaround. According to the documentation, when returning objects, they are returned in one of two ways:
OBJECT - result will be output as a numerically indexed array of row objects.
OBJECT_K - result will be output as an associative array of row objects, using first column's values as keys (duplicates will be discarded).
So, knowing that the result is an array of objects, we can get to each individual instance using a foreach construct:
$results = $wpdb->get_results( $nastySQL );
foreach($results as $index => $result)
{
// Change name column to FirstName using copy and delete
$tmp = $result->name;
unset($result->name);
$result->FirstName = $tmp;
// Remove specific row
if( $result->name == "Tom")
{
unset($results[$index]);
}
}
Below code will replace the value coming from specific field of database table, if name field has value like Reo and you want to replace it with other name like John then you can to do this via below code
$results = $wpdb->get_results( $nastySQL );
foreach($results as $key => $value){
$results[$key]->name= 'John';
}
return $results;
I'm querying a table in a db using php. one of the fields is a column called "rank" and has data like the following:
none
1-bronze
2-silver
3-gold
...
10-ambassador
11-president
I want to be able to sort the results based on that "rank" column. any results where the field is "none" get excluded, so those don't factor in. As you can already guess, right now the results are coming back like this:
1-bronze
10-ambassador
11-president
2-silver
3-gold
Of course, I would like for it to be sorted so it is like the following:
1-bronze
2-silver
3-gold
...
10-ambassador
11-president
Right now the query is being returned as an object. I've tried different sort options like natsort, sort, array_multisort but haven't got it to work the way I'm sure it can. I would prefer keeping the results in an object form if possible. I'm passing the data on to a view in the next step. although, it's perfectly acceptable to pass the object to the view and then do the work there. so it's not an issue after all. :)
thank you for your help. i'm hoping I'm making sense.
How about using this function to sort. I assume if you are getting an object you should convert object to array then use this
function arraySubSort($array, $subkey, $sort = 'asort')
{
foreach($array as $key => $value)
{
$temp[$key] = strtolower($value[$subkey]);
}
$sort($temp);
foreach($temp as $key => $value)
{
$result[] = $array[$key];
}
return $result;
}
$data = $your_array;
$field = 'ranks';
arraySubSort($data,$field);
It will sort the array with the field you assign. If you are getting multiple records its a good thing to use to sort.
Get the values in an array an sort it in PHP using natsort()
Natsort
This will work -
SELECT alphanumeric, integer FROM sorting_test ORDER BY LENGTH(alphanumeric), alphanumeric
source - Natural Sort in MySQL
I have the following array:
$masterlist=[$companies][$fieldsofcompany][0][$number]
The third dimension only exists if the field selected from $fieldsofcompany = position 2 which contains the numbers array. Other positions contain regular variables. The 3rd dimension is always 0 (the numbers array) or Null. Position 4 contains numbers.
I want to cycle through all companies and remove from the $masterlist all companies which contain duplicate numbers.
My current implementation is this code:
for($i=0;$i<count($masterlist);$i++)
{
if($masterlist[$i][2][0][0] != null)
$id = $masterlist[$i][0];
for($j=0;$j<count($masterlist[$i][2][0]);$j++)
{
$number = $masterlist[$i][2][0][$j];
$query = "INSERT INTO numbers VALUES('$id','$number')";
mysql_query($query);
}
}
Which inserts numbers and associated IDs into a table. I then select unique numbers like so:
SELECT ID,number
FROM numbers
GROUP BY number
HAVING (COUNT(number)=1)
This strikes me as incredibly brain-dead. My question is what is the best way to do this? I'm not looking for code per se, but approaches to the problem. For those of you who have read this far, thank you.
For starters, you should prune the data before sticking it into the database.
Keep a look up table that keeps track of the 'number'.
If the number is not in the look up table then use it and mark it, otherwise if its in the look up table you can ignore it.
Using an array for the look up table and with keys being the 'number' you can use the isset function to test if the number has appeared before or not.
Example pseudo code:
if(!isset($lookupTable[$number])){
$lookupTable[$number]=1;
//...Insert into database...
}
Now that I think I understand what you really want, you might want to stick with your two-pass approach but skip the MySQL detour.
In the first pass, gather numbers and duplicate companies:
$duplicate_companies = array();
$number_map = array();
foreach ($masterlist as $index => $company)
{
if ($company[2][0][0] === null)
continue;
foreach ($company[2][0] as $number)
{
if (!isset($number_map[$number])
{
// We have not seen this number before, associate it
// with the first company index.
$number_map[$number] = $index;
}
else
{
// Both the current company and the one with the index stored
// in $number_map[$number] are duplicates.
$duplicate_companies[] = $index;
$duplicate_companies[] = $number_map[$number];
}
}
}
In the second pass, remove the duplicates we have found from the master list:
foreach (array_unique($duplicate_companies) as $index)
{
unset($masterlist[$index]);
}