Failing to search for full names while querying mysql with php - php

First time asking on SO. I currently am trying to search a database where the first and last names are seperate. Example:
player_id | first_name | last_name
191 John Smith
192 Larry Citizen
193 Benjamin Example
I am trying to allow users to search this list using a full name only. I currently have the following code once the user hits submit, it calls usersearch.php.
session_start();
include '../con.php';
$player = $_POST['name'];
$sql = "SELECT * FROM characters WHERE (concat(first_name,' ',last_name)) = ($player)";
$result = mysqli_query($conn, $sql);
if (!$row = mysqli_fetch_assoc($result)) {
echo "Found no-one with the name $player. <a href='../search.php'>Try Again?</a>";
} else {
$_SESSION['selplate'] = $row['plate'];
$_SESSION['selname'] = $row['first_name, last_name'];
header("Location: ../profile.php?player=$player");
}
No matter the query it will not find users and always returns "Found no-one with the name $player. Try again?"
This was supposed to be the easy part of this project and I am pulling my hair out.
I have spent over an hour searching SO and Google to no avail so it must be my code? afaik it should work.

you need qoutes ' ' around player because its a text and also concatinated.
if you search Johnsmith it will return nothing
if you search John Smith it will give you result, because in your concat you are adding a space between words
"SELECT * FROM characters WHERE concat(first_name,' ',last_name) =('".$player."')"

I would change it to a fulltext index on both first and last name, change the word min on full text indexes. then I would search using ( some guy as the name )
MATCH( first, last )AGAINST('+"some" +"guy"' IN BOOLEAN MODE )

delete the white-space from concat function in query and other thing is use $player = str_replace(' ','',trim($_POST['name'])) instead of $player = $_POST['name'].
$SQL = "SELECT * FROM TABLE_NAME WHERE concat(first_name,last_name) = '".$player."'"
i suggest PDO with prepared statements...
assume you are searching 'benjamin example' and query will check for 'benjamin example' so str_replace will output as benjaminexample.and the concated first_name and last_name will match it.
hope it help.
ignore if it sound silly.

Related

checking for the existence of a word a mysql row(php)

i have a mysql table users like this:
id username following
15 one ,13,14,16,17,
14 two ,76,43,13,
13 three null
now three has 0 following and 2 followers.
and i want a query to check for all users who have ,13, in the following row
Something like this:
$query = mysql_query('SELECT * FROM users WHERE following has ",13,"');
but works.
I can select all the following of each user and do this:
if (strpos($result_from_query,',13,') !== false) {
echo $fetch['username'];
}
Have you tried using LIKE?
$query = mysql_query('SELECT * FROM users WHERE following LIKE "%,13,%"');
The % characters before and after the ,13, string act as a wildcard allowing any characters to be there, so will find ,13, in any position in the string.
Also, as an aside, #Jay Blanchard has suggested using the IN operator (in his answer)
I would use IN for greater flexibility if the value in the following column is an array.
SELECT *
FROM `users`
WHERE `following` IN(13)
Assuming that the numbers always have starting and trailing commas you can use:
$query = mysql_query('SELECT * FROM users WHERE following LIKE "%,13,%"');
Please read up on LIKE statements for more info

Matching variable to two columns joined (PHP)

A previous variable from a query gave me a value $name. I need to find the user id associated with that name, however in my users table I have two fields, firstName and lastName.
I cannot explode $name as I have both cases of double names (e.g. John Eric Smith) and last names (e.g. Jan van der Worde), so my attempt was to find a way to match firstName + lastName with $name.
My attempt was this:
$drid = "SELECT id FROM users WHERE CONCAT(firstName,' ',lastName)='$name'";
$rest = mysql_query($drid);
while ($row = mysql_fetch_row($rest)) {
$driver_id = $row[0];
}
Unfortunately, nothing comes out as a result for $driver_id (whereas $name returns a result).
Thank you for your help!
Are you looking for something like this:
<?php
$drid = "SELECT id FROM users WHERE CONCAT(firstName, ' ', lastName) LIKE '%".$name."%'";
$rest = mysql_query($drid);
while ($row = mysql_fetch_row($rest)) {
$driver_id = $row[0];
}
?>
I would suggest adding a new fullname field or using a temp table rather than using the concat, for performance reasons.
https://stackoverflow.com/a/29285246/3923450 should work though if you are looking for a temp solution

SQL-PHP Grabbing information from end of URL and compare with row in database

Ok so this uses two things, One is vbulletins forums with a steam plugin which allows users to register on my forums using there steam account, It also uses API from a website at http://7daystodie-servers.com which is a voting site that has API I can use as a reward system in one way or another. Everything I have been doing works good so far the only problem I have now is updating the vbulletin database with the correct information if $pullinfo == 1, Here is my code as is.
$connection = mysql_connect("$hostname","$data_username","$data_password") or die ("Couldn't connect to server.");
$db = mysql_select_db("$db_name", $connection) or die("Couldn't select database.");
$sql1 = mysql_query("SELECT DISTINCT steam_link, username FROM user WHERE steam_link IS NOT NULL AND TRIM(steam_link) <> '' AND username IS NOT NULL AND TRIM(username) <> ''");
while($row1 = mysql_fetch_array($sql1)){
$steamid = substr($row1[steam_link], 0, 17);
$checkvoted = 'http://7daystodie-servers.com/api/?object=votes&element=claim&key=wc5ablok4zpc1w3ljgofp5yuuedrgv8ycs6&steamid='.$steamid;
$pullinfo = file_get_contents($checkvoted);
if ($pullinfo == 2){
echo ''.$row1[username].' has already claimed reward for voting...<br />';
}
if ($pullinfo == 1){
$username = $row1[username];
echo ''.$row1[username].' has not claimed reward for voting...<br />';
$sql2 = mysql_query("UPDATE user SET `reputation`=(`reputation`+10) WHERE substr($row[steam_link], 0, 17) = $steamid");
}
if ($pullinfo == 0){
echo ''.$row1[username].' has not voted...<br />';
}
echo ''.$row1[username].''.$pullinfo.'<br />';
}
As you can see it does two things, One is gets the information from the API url which is a "0" or a "1" then I am trying to update the database information based on one factor, $row[steam_link] and $steamid. Issue I have is both of these are pulled from the database from the start they are the same thing. So how would I compair the return of the API with the $steamid so I can UPDATE database?
Your UPDATE statement needs to identify which rows are to be updated.
The SELECT statement pulled steam_link and username columns, seems likely that these are the columns you want to reference in predicates in the UPDATE statement.
Since the original SELECT had a DISTINCT keyword, and the query was from the user table, we assume that there may be multiple rows in the table with the same username and steam_link, and that we may only want to add reputation to one of those rows.
$sql = "UPDATE user u
SET u.reputation = u.reputation + 10
WHERE u.steam_link = '" . mysql_real_escape_string( $row1['steam_link'] ) . "'
AND u.username = '" . mysql_real_escape_string( $row1['username'] ) . "'
LIMIT 1";
if(!mysql_query($sql)) {
echo "error: " . mysql_error();
}
But, I'm just guessing which rows in user table you want to update, all of the rows that have username and steamlink matching values pulled by the query, or all of the rows with a matching username, or all rows with a matching steam_link. (I'm just guessing.)
Your existing code has a references to $row; we see $row1 being assigned values, but we don't see any assignments to $row.
I'm seeing what looks like array references $row1[username], but string keys are usually enclosed in single quotes, e.g. $row1['username'].
FOLLOWUP
If we want to match rows that have steam_link column starting with a specific set of characters, for example, 17 specific digit characters 79546325458103548, we could use a LIKE comparison operator in a predicate (that is, a condition in the WHERE clause:
AND u.steam_link LIKE '79 5463 25458103548%'
Note that the '%' character at the end is a special wildcard character (in the context of the right side of a LIKE comparison). That will match any number of characters (zero, one or more)
If we want a more specific match, 17 specific digits, followed by exactly one character that is a '0' or '1' digit character, we could use a regular expression comparison:
AND u.steam_link REGEXP '^79546325458103548[10]$`
As another option, we could also use a SUBSTRING function around the steam_link column, but we typically try to avoid doing that when possible, we prefer to use comparisons against bare columns when possible.
There are lots of other alternatives that would accomplish the same thing as the expressions above. If we wanted to do the same thing as the REGEXP as above, we could do something overly obfuscated and tedious:
AND SUBSTRING(u.steam_link,1,2) = '79'
AND SUBSTRING(u.steam_link,3,4) = '5463'
AND SUBSTRING(u.steam_link,7,9) = '254581035'
AND SUBSTRING(u.steam_link,16,3) IN ('480','481')
If we wanted to match just the 18th character of steam_link:
AND SUBSTRING(u.steam_link,18,1) = '0'
It's still not clear (to me) which rows you want to update. But maybe this helps you with some ideas about what is possible.

how do I loop inside a loop with PHP in MySQL?

table persons
name | details
------------------
mathew| tax,home,car,insurance
john | job,tax,employ
neil | tax,home,car,job
yancy | consultant,rent,family
lucy | home,car,insurance
I want loop through this table and search with details then saved result to another table called persons1
name | names
------------------
mathew| neil,lucy,john
neil | mathew,lucy,john
john | mathew,lucy,neil
so far I coded something like below but not working
mysql_connect("localhost", "root", "pass");
mysql_select_db("database");
$query = "SELECT * FROM persons";
$result = mysql_query($query);
while($r = mysql_fetch_array($result))
{
$exp = explode(",",$r["details"]);
$sql = mysql_query('SELECT * FROM persons WHERE MATCH (tags) AGAINST ("+$exp[0]" "+$exp[1]" "+$exp[2]" IN BOOLEAN MODE)');
$result = array();
while($row = mysql_fetch_assoc($sql))
{
array_push($result,$row['name']);
$name = implode(",",$result);
mysql_query("INSERT INTO person_new (name,names) VALUES (\"".$r["name"]."\", \"".$name."\")");
}
}
IT is very sad that nobody can give an answer to my question about my code. instead of looking into my design I request you to look into my code and tell me where I made a mistake..i am doing something different than what it sees and this is why I request you to check my code...
Your problem would be better solved via database normalization.
Storing data like tax,home,car,insurance in a single column, then parsing it to search is a Very Bad Idea.
First of all, it'd be nice if you'd tell us what doesn't work.
Having said that, I suspect (at least one of) your error(s) is here:
'SELECT * FROM persons WHERE MATCH (tags) AGAINST ("+$exp[0]" "+$exp[1]" "+$exp[2]" IN BOOLEAN MODE)'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This will literally give you the query AGAINST ("+$exp[0]" "+$exp[1]" "+$exp[2]" IN BOOLEAN MODE), which is likely not what you want. You need to concatenate the string, or use a double quoted string:
'SELECT ... AGAINST ("+' . $exp[0] . '" "+' . $exp[1] . '" "+' . $exp[2] . '" IN BOOLEAN MODE)'
or
"SELECT ... AGAINST (\"+$exp[0]\" \"+$exp[1]\" \"+$exp[2]\" IN BOOLEAN MODE)"
I'm with #Dolph though, this is not a good database structure, and if you're going to redesign it later anyway (careful with saying "later", that usually never happens), you should just do it now.

filter mySQL database with multiple words in any order in Concatenated field

I have Concatenated in mySQL to produce a field that I can search with. This contains animal as well as owner names and addresses for a client database. I need to be able to search by animal name, owner names and postcode in any order.
Thus if if my name is john smith and i own a dog called Fido and live in postcode AB1 2CD, I want the search to be yield results if any of the following are entered:
"john fido AB1"
"john AB1"
"AB1 john"
"AB1 fido"
"fido 2CD"
"2CD"
"fido"
etc... i.e any of the fields in any order, and also not complete words either so "john fido AB1" should yield the same result as "jo fi AB1"
I currently have this PHP code, taking a single text field on my search page, exploding then imploding it to add % between the search terms:
$list = explode(' ',$_GET["q"]);
$q = implode('%%', $list);
if (!$q) return;
$sql = "SELECT DISTINCT owner.AddressPrim, owner.PostcodePrim,
owner.OwnerSurnamePrim,owner.OwnerForenamesPrim,owner.OwnerID
FROM owner
Inner Join patient ON owner.OwnerID = patient.OwnerID
WHERE CONCAT_WS(' ',owner.AddressPrim, owner.PostcodePrim,
owner.OwnerForenamesPrim,owner.OwnerSurnamePrim,patient.AnimalName) LIKE '%$q%'";
This works for "AB1 john" and "john fido" but not "fido john" as it is out of order in the concatenated field.
Any help greatly appreciated
I think you're going to have to split the keywords and add a query for each keyword in the string of keywords.
So first (in PHP), split the query string and dynamically generate your SQL query, then send it to the database. Here's some pseudocode to show you what I mean:
$keywords = explode(' ', $q);
$sql = "SELECT DISTINCT owner.AddressPrim, owner.PostcodePrim,
owner.OwnerSurnamePrim,owner.OwnerForenamesPrim,
owner.OwnerID
FROM owner
Inner Join patient ON owner.OwnerID = patient.OwnerID";
$first = true;
foreach($keyword in $keywords):
if($first):
$sql += " WHERE ";
$first = false;
else:
$sql += " AND ";
$escaped = mysql_real_escape_string($keyword);
$sql += " CONCAT_WS(' ',owner.AddressPrim, owner.PostcodePrim,
owner.OwnerForenamesPrim,owner.OwnerSurnamePrim,patient.AnimalName)
LIKE '%$escaped%'";
But do beware, this is not going to be anywhere near fast for the size of tables you'll probably encounter in daily operation. You may want to look into a better way of doing fulltext search, whether it means using a library or making a cross-reference table of keywords maintained by triggers.
MySQL's fulltext search (MyISAM tables only!) could be useful to you.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
You can try this http://www.sphinxsearch.com/
You need dedicated server to run this thing, but if you have one, sphinx will easily solve your problem and your queries won't load database.

Categories