I need to search for a word inside an MDB ACCESS database using PDO and PHP.
The problem is that inside the database I can have a field called CODE_NUMBER and it can contain dot or comma like:
12.11.34
The user when it search using a custom form for an article in database, maybe search without dots or other special chars... so in the example above, it can write inside the input box something like this:
1211
Then press enter.
I'd like to get 12.11.34 as a valid result in this case, ignoring search for dot.
The problem is that PDO for MDB ACCESS doesn't support REPLACE command:
This version for mysql is working:
$code = "1211";
$rs = $db->prepare('SELECT Products.* FROM Products WHERE REPLACE(Products.CODE_NUMBER, ".", "") LIKE ?');
$rs->execute(array("%" . $code . "%"));
$ris = $rs->fetchAll(PDO::FETCH_ASSOC);
But the same one using MDB access doesn't work!
So I tried this way from here: Search using REPLACE in a SELECT with PDO and .MDB ACCESS, with PHP
$code = "1211";
$code = implode("[.]", str_split($code )) . "[.]";
$rs = $db->prepare('SELECT Products.* FROM Products WHERE Products.CODE_NUMBER LIKE ?');
$rs->execute(array("%" . $code . "%"));
$ris = $rs->fetchAll(PDO::FETCH_ASSOC);
But it doesn't work.
Any suggest?
Related
Let me explain fast what i want to do!
I want to show similar rows from my database by a PHP term.
I have a table called "games" and a column called "title" that titles are looks like "Rockstar - GTA V".
So i want to remove all words after dash and use new string as keyword to search in database.
My CMS use this code to show post title inside the loop:
$_smarty_tpl->tpl_vars['game']->value['title']
I just found a code to convert "Rockstar - GTA V" to "Rockstar":
<?php $mygame = strstr($_smarty_tpl->tpl_vars['game']->value['title'], '-', true); echo($mygame); ?>
When i put this code in my "Single template file", it work fine and trim the title as i want and it work good in every game's single page.
So i want to make a section in single page to display all games made by that company (i mean that trimmed word from title). I tried some codes and nothing! This is what i tried:
<?php
$connect = mysqli_connect("localhost", "dbname", "dbpass", "dbuser");
$connect->set_charset('utf8mb4');
mysqli_set_charset($link, 'utf8mb4');
$gamecompany = strstr($_smarty_tpl->tpl_vars['game']->value['title'], '-', true);
$query = 'SELECT * FROM games WHERE title = "'.$gamecompany.'" ORDER BY game_id ASC LIMIT 50';
$result = mysqli_query($connect, $query);
if(mysqli_num_rows($result) > 0)
{
$output .= '<div class="list">';
while($row = mysqli_fetch_array($result))
{
$output .= '<li class="game">'.$row["title"].'</li>';
}
$output .= '</div>';
echo $output;
}
else
{
echo 'Nothing Found';
}
?>
So i used $gamecompany to trim and get a game's company and use it as a keyword in query. But everytime it just show "Nothing Found". When i have some games with keyword "Rockstar" in my database But it won't display that and just pass the conditions statement and can't show nothing.
Tried another keywords (Directly in my code) but won't work!
And one note: My titles are in "Arabic" language and it should be UTF8. Is this my problem? or just a wrong coding?
Using LIKE you can find all occurences with 'Rockstar', but to be safe, convert it to lower case and remove any extra spaces that might occur. Also, lets protect ourselves from SQL attacks with a prepared statement.
$gamecompany = strtolower(trim(strstr($_smarty_tpl->tpl_vars['game']->value['title'], '-', true))); // put it in lower case, trim any excess white space
$query = 'SELECT * FROM games WHERE LOWER(title) LIKE ? ORDER BY game_id ASC LIMIT 50';
$stmt = $conn->prepare($query);
$value = "%$gamecompany%"; // The % allows us to find any titles that have our search string in them
$stmt->bind_param("s", $value);
$stmt->execute();
$result = $stmt->get_result();
For you requirement
title = "'.$gamecompany.'"
is not going to work. You'll need to either use likewise search or full-text search
Likewise
title like '$gamecompany'
Full-Text - For full-text to work, you'll need to have full-text index for that column
MATCH (title) AGAINST (:gamecompany IN NATURAL LANGUAGE MODE)
You can create Full-text index like this
ALTER TABLE games ADD FULLTEXT(title)
Try using the LIKE keyword inside the query , and for the Arabic part make sure both the web app and the database uses the same encoding , i once had this problem and when both of them followed the same encode it worked out.
I have a php search form with two fields. One for $code another for '$name'.The user uses one or the other, not both.
The submit sends via $_POST.
In the receiving php file I have:
SELECT * FROM list WHERE code = '$code' OR name = '$name' ORDER BY code"
Everything works fine, however I would like that $code is an exact search while $name is wild.
When I try:
SELECT * FROM list WHERE code = '$code' OR name = '%$name%' ORDER BY code
Only $code works while $name gives nothing. I have tried multiple ways. Changing = to LIKE, putting in parentheses etc. But only one way or the other works.
Is there a way I can do this? Or do I have to take another approach?
Thanks
If you only want to accept one or the other, then only add the one you want to test.
Also, when making wild card searches in MySQL, you use LIKE instead of =. We also don't want to add that condition if the value is empty since it would become LIKE '%%', which would match everything.
You should also use parameterized prepared statements instead of injection data directly into your queries.
I've used PDO in my example since it's the easiest database API to use and you didn't mention which you're using. The same can be done with mysqli with some tweaks.
I'm using $pdo as if it contains the PDO instance (database connection) in the below code:
// This will contain the where condition to use
$condition = '';
// This is where we add the values we're matching against
// (this is specifically so we can use prepared statements)
$params = [];
if (!empty($_POST['code'])) {
// We have a value, let's match with code then
$condition = "code = ?";
$params[] = $_POST['code'];
} else if (!empty($_POST['name'])){
// We have a value, let's match with name then
$condition = "name LIKE ?";
// We need to add the wild cards to the value
$params[] = '%' . $_POST['name'] . '%';
}
// Variable to store the results in, if we get any
$results = [];
if ($condition != '') {
// We have a condition, let's prepare the query
$stmt = $pdo->prepare("SELECT * FROM list WHERE " . $condition);
// Let's execute the prepared statement and send in the value:
$stmt->execute($params);
// Get the results as associative arrays
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
The variable $results will now contain the values based on the conditions, or an empty array if no values were passed.
Notice
I haven't tested this exact code IRL, but the logic should be sound.
I have a sql query that is generated using php. It returns the surrogate key of any record that has fields matching the search term as well as any record that has related records in other tables matching the search term.
I join the tables into one then use a separate function to retrieve a list of the columns contained in the tables (I want to allow additions to tables without re-writing php code to lower ongoing maintenance).
Then use this code
foreach ($col_array as $cur_col) {
foreach ($search_terms_array as $term_searching) {
$qry_string.="UPPER(";
$qry_string.=$cur_col;
$qry_string.=") like '%";
$qry_string.=strtoupper($term_searching);
$qry_string.="%' or ";
}
}
To generate the rest of the query string
select tbl_sub_model.sub_model_sk from tbl_sub_model inner join [about 10 other tables]
where [much code removed] or UPPER(tbl_model.image_id) like '%HONDA%' or
UPPER(tbl_model.image_id) like '%ACCORD%' or UPPER(tbl_badge.sub_model_sk) like '%HONDA%'
or UPPER(tbl_badge.sub_model_sk) like '%ACCORD%' or UPPER(tbl_badge.badge) like '%HONDA%'
or UPPER(tbl_badge.badge) like '%ACCORD%' group by tbl_sub_model.sub_model_sk
It does what I want it to do however it is vulnerable to sql injection. I have been replacing my mysql_* code with pdo to prevent that but how I'm going to secure this one is beyond me.
So my question is, how do I search all these tables in a secure fashion?
Here is a solution that asks the database to uppercase the search terms and also to adorn them with '%' wildcards:
$parameters = array();
$conditions = array();
foreach ($col_array as $cur_col) {
foreach ($search_terms_array as $term_searching) {
$conditions[] = "UPPER( $cur_col ) LIKE CONCAT('%', UPPER(?), '%')";
$parameters[] = $term_searching;
}
}
$STH = $DBH->prepare('SELECT fields FROM tbl WHERE ' . implode(' OR ', $conditions));
$STH->execute($parameters);
Notes:
We let MySQL call UPPER() on the user's search term, rather than having PHP call strtoupper()
That should limit possible hilarious/confounding mismatched character set issues. All your normalization happens in one place, and as close as possible to the moment of use.
CONCAT() is MySQL-specific
However, as you tagged the question [mysql], that's probably not an issue.
This query, like your original query, will defy indexing.
Try something like this using an array to hold parameters. Notice % is added before and after term as LIKE %?% does not work in query string.PHP Manual
//Create array to hold $term_searching
$data = array();
foreach ($col_array as $cur_col) {
foreach ($search_terms_array as $term_searching) {
$item = "%".strtoupper($term_searching)."%";//LIKE %?% does not work
array_push($data,$item)
$qry_string.="UPPER(";
$qry_string.=$cur_col;
$qry_string.=") LIKE ? OR";
}
}
$qry_string = substr($qry_string, 0, -3);//Added to remove last OR
$STH = $DBH->prepare("SELECT fields FROM table WHERE ". $qry_string);//prepare added
$STH->execute($data);
EDIT
$qry_string = substr($qry_string, 0, -3) added to remove last occurrence of OR and prepare added to $STH = $DBH->prepare("SElECT fields FROM table WHERE". $qry_string)
I am trying to load all records from the database that have been created by the current logged on user in Joomla, im not sure if its possible to have php inside a mysql query though ?, if not how would I go about doing this otherwise ?
SELECT
leadname,
businessname,
postcode,
gasoiluser,
dervuser,
kerouser,
cf_uid,
cf_id
FROM
#__chronoforms_data_addupdatelead
WHERE createdby = '<?php
$user =& JFactory::getUser(); echo $user->get('name') ; ?>'
ORDER BY cf_created DESC
Of course you can access PHP variables for creating the query - as the #__ prefix suggests, you're already running your query from "inside Joomla". Which means it is in php, and something like this should do what you want:
$user =& JFactory::getUser();
$db =& JFactory::getDBO();
if (!$user->guest) {
$query = 'SELECT leadname, businessname, postcode, gasoiluser, '.
' dervuser, kerouser, cf_uid, cf_id '.
' FROM #__chronoforms_data_addupdatelead '.
' WHERE createdby = '.$db->Quote($user->name)).
' ORDER BY cf_created DESC';
$db->setQuery($query);
}
But a little more context would help us see what you'll have to do exactly - what's the code around the SQL query - is it in a php file?
Remember, echo prints to the Response, which is not what you want to do in this case, you want to change the query; so just concatenate the variable content to your query, as shown above; and you should actually be already be in php mode where this query is defined, so the <?php tag is of no use (but again, too few context to be sure about this)!
mysql is a database server that accepts a string and returns either result set or an error
string passed to mysql must be proper SQL statement
what you have in your question is not proper SQL statement, it is a string waiting to be parsed by PHP and whoever knows by who else
this part is PHP for sure:
<?php $user =& JFactory::getUser(); echo $user->get('name') ; ?>
this part is something like a placeholder for correct table name that is replaced at runtime of whatever you got this query from(supposedly joomla):
#__chronoforms_data_addupdatelead
if you want to run that query you must to figure out what to substitute with the aforementioned blocks
Hey, I am wondering how to extract the data from a table in a database onto a table in a page (users.php),
For example:
I want to be able to get all of the usernames and all the id's from my database onto a table.
So if I have in my database:
1 - Fred
2 - Frank
3 - Margret
It will see that I have them user's and id's in the database and print them onto a table.
Any help would be great,
Thanks.
Connect to your database. Host is the location, like localhost if its on your computer, or on the same server as your code. User and Password are self explanatory.
mysql_connect("host", "user", "pass");
The name of the database you want to access.
mysql_select_db("database");
The actual mysql query.
$result = mysql_query('SELECT `User_Name`, `User_ID` FROM TABLE');
Sort it into an array
while($temp = mysql_fetch_array($result)
{
$id = $temp['User_ID'];
$array[$id]['User_ID'] = $id;
$array[$id]['User_Name'] = $temp['User_Name'];
}
Turn the array into a table. (You could skip the last step and go right to this one.
$html ='<table><tr><td>User ID</td><td>User Name</td></tr>';
foreach($array as $id => $info)
{
$html .= '<tr><td>'.$info['User_ID'].'</td><td>'.$info['User_Name'].'</td></tr>';
}
echo $html . '</table>';
Or, the formatting you wanted
$html ='User Id - User Name';
foreach($array as $id => $info)
{
$html .= $info['User_ID'].' - '.$info['User_Name'].'<br>';
}
echo $html;
(For this answer, I will use the mysqli extension -- you could also want to use PDO ;; note that the mysql extension is old and should not be used for new applications)
You first have to connect to your database, using mysqli_connect (And you should test if the connection worked, with mysqli_connect_errno and/or mysqli_connect_error).
Then, you'll have to specifiy with which database you want to work, with mysqli_select_db.
Now, you can send an SQL query that will select all data from your users, with mysqli_query (And you can check for errors with mysqli_error and/or mysqli_errno).
That SQL query will most likely look like something like this :
select id, name
from your_user_table
order by name
And, now, you can fetch the data, using something like mysqli_fetch_assoc -- or some other function that works the same way, but can fetch data in some other form.
Once you have fetched your data, you can use them -- for instance, for display.
Read the pages of the manual I linked to : many of them include examples, that will allow you to learn more, especially about the way those functions should be used ;-)
For instance, there is a complete example on the page of mysqli_fetch_assoc, that does exactly what you want -- with countries insteand of users, but the idea is quite the same ^^
You can do something like the following (using the built-in PHP MySQL functions):
// assuming here you have already connected to the database
$query = "SELECT id,username FROM users";
$result = mysql_query($query, $db);
while ($row = mysql_fetch_array($result))
{
print $row["id"] . " - " . $row["username"] . "\n";
}
which will give you (for example):
1 - Fred
2 - Frank
3 - Margret
Where I've put the print statement, you can do whatever you feel like there eg put it into a table using standard HTML etc.