Fetching a specific SQL column's content - php

I have a MySQL table containing columns for user IP (IP) and their name (Name). I want to compare the user's browser IP to the IP column the SQL table, and save their name to a PHP variable $name should an IP match be found.
I'm using $ip = $_SERVER['REMOTE_ADDR'] to save the browser's IP. How would I go about comparing this variable to the IP addresses in the SQL database? I tried $getname = mysql_query("SELECT Name FROM MyTable WHERE IP=$ip"); but this seems to return a Resource ID.
My apologizes if the question seems awfully elementary; I'm rather new to SQL (and PHP, for that matter). Also, I'm not in need for a secure way of authenticating for this one.

Use below code, after firing the query you have to iterate the result to get the output.
$getname = mysql_query("SELECT Name FROM MyTable WHERE IP='$ip'");
if(mysql_num_rows($getname)>0)
{
while($row = mysql_fetch_array($getname))
{
echo $row['Name'];
}
}

wrap the value of IP with single quote.
mysql_query("SELECT Name FROM MyTable WHERE IP='$ip'");

Related

is it possible to search a value in multiple columns using in clause in mysql?

I wonder if it is possible to search a value in columns using in clause having column names as in elements.
for instance :
$username_or_mail = 'value';
select * from users where $username_or_mail in(username,email);
where username and email are column names in table users.
I tried this and seems that it is working but i want to be sure if i'm right.
Would I be right in assuming you're using this for a "Enter your username or e-mail address and password to login" login form?
If so, then your SQL code is correct, but hints at a possible design flaw: what happens if someone has a username that is also the email address of another user? This could be used as a malicious attack (i.e. hijack another user's account by making your username equal to the victim's email address).
There is a solution/workaround: simply check for the '#' character and ensure that email addresses contain # and similarly ensure that no username contains # either.
...and if you're going to do that logic, then you might as well optimize the SQL and skip having to check multiple columns (psuedocode):
if( $usernameOrEmail contains '#' ) {
registerParameter("#email", $usernameOrEmail);
$sql = "SELECT ... WHERE EmailAddress = #email"; // note that "#email" is the syntax for query parameters in MySQL.
} else {
registerParameter("#userName", $usernameOrEmail);
$sql = "SELECT ... WHERE UserName = #userName";
}

Doing a second search automatically

I have PHP code to do a simple MySQL database search with only two columns of data. I suspect I am probably already going the long way around when I could simply do it a different way.
I have a form that you can put in a name or an IP address and it will search for either of them in the database, and output the results. Each name can only have one IP address (the last one they used) (full unique names will only have 1 result, or multiple results if partial names match multiple accounts), but an IP address can have multiple names (people who use multiple accounts on the same IP).
What I want to do is have it so if you search for a name, it will do the regular single result (if the full unique name was typed), but then under it, do a secondary search for the IP if only the NAME was searched for in the form.
"You search for NAME has returned these results: {results}. We also
found these accounts who have used the same IP address: {results
matching the same IP from the first result of the Name search}".
Here is the code I have so far:
(Some cleanup since I am using GET)
$iplookup = strtolower($_GET['iplookup']);
$iplookup = stripslashes($iplookup);
$iplookup = strip_tags($iplookup);
$iplookup = preg_replace('/[^A-Za-z0-9\._]/','',$iplookup);
$sql = mysql_query("select
* from banlistip where name like '%$iplookup%' OR lastip like '%$iplookup%'
");
if (empty($iplookup)) {
echo '<br><b>You left the search form empty.</b>';
} else {
while ($row = mysql_fetch_array($sql)) {
echo '<br/> Name: '.$row['name'];
echo '<br/> Player IP: '.$row['lastip'];
echo '<br/><br/>';
}
}
And then right here it would get that $row['lastip'] variable and then do a search for that, which would be the equivalent of just searching an ip address in the first place.
The whole purpose of this is to eliminate a couple of steps and see all of the desired results at once. Usually, in order to do an IP search, I have to search the name, highlight + copy the ip, go back to the form, and then search the IP.
The table with two columns named "name" and "lastip" respectively have data like this:
player1 111.111.111.111
player2 222.222.222.222
player3 111.000.111.000
player4 222.000.222.000
altaccount1 111.000.111.000
altaccount2 222.222.222.222
(If you searched for Player2, you would get one result, since it is a unique name. If you searched for the IP of Player2, you would get two results [player2 + altaccount2], since there is an alternate account that uses the same IP address.)
(Please excuse this very long post. I just want to provide as much details as I can, I have tried to research this, but having a block right now. Thanks so much, and again, sorry for making you read all of this.)
SELECT * FROM banlistip
WHERE lastip = (SELECT DISTINCT lastip FROM banlistip WHERE name LIKE '%$iplookup%' OR lastip LIKE '%$iplookup%')
I think what you're trying to do needs 2 seperate SQL strings, and call whichever is required for the data provided.
So if $iplookup is clearly an IP (use regex check), then:
$sql = "SELECT * FROM banlistip WHERE lastip LIKE '%$iplookup%'";
else you will use:
$sql = "SELECT * FROM banlistip WHERE name LIKE '%$iplookup%'";
A Regex you can use to check this with preg_match(), curtousy of regular-expressions.info:
$regex = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/';
if (preg_match($regex, $iplookup)) {
// Call IP SQL
} else {
// Call Name SQL
}

Pairing inputted names to previously stored names

I currently have this table.
Names
Two fields, ID and Names. Example data would be 1 | Harry.
Now what i am planning on doing is that if someone enters in something like Henry in my form, it will search my database for a result that begins with "H" Then if their are multiple results, it will see if there are any results that are "He" if their isn't it will fallback to the previous result from "H".
The only thing i can think of doing is this,
$inputted_name = "Henry";
$query = mysql_query("SELECT `name` FROM `names`");
while($row = mysql_fetch_array($query)){
$stored_name = $row['name'];
if($stored_name[0] == $inputted_name[0]){
if($stored_name[1] == $inputted_name[1]){
$result = $stored_name;
break;
} else {
// continue looking but then return the first result that matched one letter?
}
}
}
Now i am sure this can't be the best way to do it. Would it be possible in a query? I'm just really not sure where to look for a sensible answer for this one.
change
mysql_query("SELECT name FROM names");
to
mysql_query("SELECT name FROM names WHERE NAME='".$inputted_name."'");
and check you have more than one answer.
Note this is a bad way to do it if your name comes from a non controlled source, such as a web page, as it would allow a SQL injection, and then you would need parameters, but for your example it would work.
Edit: Now I read your question again, yes, you would need parameters or escaping such as:
$name = mysql_real_escape_string($inputted_name);
mysql_query("SELECT `name` FROM `names` WHERE NAME='".$=name."'");
Also, don't try and do in code what the database can do easily (like search for characters). Your code is almost always going to be worse than the database for doing a search, leave it to the database.

php generate a string and check from mysql with not exist

I want to generate a string to post a url. Then make the post url like: http://www.mydomain.com/post/afCeYk, and store this url in the mysql. In order to avoid a repeat url , I think first should check the mysql whether the url has already existed. In my code, I just check once, I can not ensure the second generate string hasn't already existed. So how do I make a loop?
$shufstr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$rdstr = substr(str_shuffle($shufstr),0,6);
$query = mysql_query("select * from table where post_url = '".$rdstr."'");
if(mysql_num_rows($query)>0){
//insert the url rules into db
}else{
//generate a new string and check the db again
}
You should query the database once to collect all of the data from the table, then generate a string and check it against the array you get.
As opposed to querying the database over and over, this has a performance benefit.
(not actual code)
$url_list = query("SELECT `post_url` FROM `table`");
do {
$random_string = generate_random_string();
}
while(!in_array($random_string, $url_list));
In addition, make sure no duplicate is entered by making the column UNIQUE.
You can use a while loop, but it would get pretty slow after you have a few thousand URLs saved:
$shufstr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$validString=false;
while(!$validString){
$rdstr = substr(str_shuffle($shufstr),0,6);
$query = mysql_query("select * from table where post_url = '".$rdstr."'");
if(mysql_num_rows($query)==0){ //This is also different from your code as you don't want to do the insert if there is 1+ row with that url.
$validString=true;
//insert the url rules into db
}
}
If it were my project, I would add a UNIQUE constraint on the post_url column itself, this will ensure that no duplicates will be entered from any point of entry (app, command line, etc). More info on MySQL unique.

Bad Characters with inet_pton() PHP Function *Not Zend* Piwik location_ip issue

I'm trying to interact with a Piwik database that we installed on our server. Inside the Piwik database, the value for a stored ip address is inserted with inet_ntop(). I'm trying to decode those values and pull them out with inet_pton() so I can run a query to find a customers ip address in the Piwik database that's been stored in our local database.
The issue comes when I'm building the query. I take the stored address in the db and run it through inet_pton() like so...
$data = mysql_fetch_assoc(mysql_query("SELECT ip_address FROM data_table WHERE id = 1"));
$more_data = mysql_fetch_assoc(mysql_query("SELECT location_ip FROM piwik_log_visit WHERE location_ip = '".inet_pton($data['ip_address'])."'"));
Where the problem comes in is inet_pton($data['ip_address']) will display random characters (sometimes) included along with black-diamond question marks. It comes back with a mysql_error that says the query is invalid (because of the bad characters). I tried adding mysql_set_charset("utf8"); before the query was run with no (good) results.
Any idears?
Thanks!
$data = mysql_fetch_assoc(mysql_query("SELECT ip_address FROM data_table WHERE id = 1"));
$hexip = bin2hex(inet_pton($data['ip_address']));
$more_data = mysql_fetch_assoc(mysql_query("SELECT location_ip FROM piwik_log_visit WHERE hex(location_ip) = '$hexip'"));
In order to have mysql and php not throw an error, you need to convert the binary output of inet_pton to hex and then compare the mysql stored hex(location_ip) value to the $hexip variable.
Binary story:
$bin_ip = '0x'.bin2hex(inet_pton($data['ip_address']));
"SELECT location_ip FROM piwik_log_visit WHERE hex(location_ip) = $bin_ip"

Categories