Script to update mysql not working - php

Okay so I have a PHP script that makes a user an artist if vote is high enough. The first part of the script works (the part that does the voting). However, the second part of the script that makes a user an artist does not. It worked before on localhost but is not working on live server for some reason. Either the script has changed and I didn't notice it or there's something wrong with my server config.
I know I should be using mysqli but please don't mention that I am working on it.
To explain how the system works, a form on the voting page is posted to this script and it all runs from there.
There is no error in the error log. Updating the table for //make an artist if vote high enough just doesn't work.
Here's the script:
<?php
session_start();
include("../database.php");
$username = $_SESSION["username"];
$artistname = htmlspecialchars(mysql_real_escape_string($_POST['artistname']));
$trackname = htmlspecialchars(mysql_real_escape_string($_POST['trackname']));
$trackurl = htmlspecialchars(mysql_real_escape_string($_POST['trackurl']));
$flag = 0; // Safety net, if this gets to 1 at any point in the process, we don't upload.
if(isset($_POST['yes'])){
//code runs if vote is yes
//check if user hasnt already voted on track
$result = mysql_query("SELECT username FROM voted WHERE voted='$artistname' AND trackname='$trackname' AND username='$username'")or die(mysql_error());
$check2 = mysql_num_rows($result);
if ($check2 != 0) {
echo('<t1>Sorry, you have already voted on this track. <b>Click next track.</b> </t1>');
$flag = $flag + 1;
}
//code runs if everything is okay
if($flag == 0){
mysql_query("UPDATE members SET vote = vote+1 WHERE artistname='$artistname'
");
echo '<t1><b>You liked the track "'.$trackname.'" by "'.$artistname.'"</t1></b>';
mysql_query("INSERT INTO voted (username, voted,trackname, yesno)
VALUES ('".$username."','".$artistname."','".$trackname."', 'yes')")
or die(mysql_error());
//make an artist if vote high enough
$vote = mysql_query("SELECT vote FROM members WHERE artistname='$artistname'")or die(mysql_error());
if ($vote > 50) {
$artisturl = htmlspecialchars(mysql_real_escape_string(str_replace(' ', '',$_POST['artistname'])));
mysql_query("UPDATE members SET artist='Y', image1='../files/noprofile.jpg', artisturl='$artisturl' WHERE artistname='$artistname'
")or die(mysql_error());
mysql_query("UPDATE tracks SET artist='Y', artisturl='$artisturl' WHERE artistname='$artistname'
")or die(mysql_error());
//email user that has just been made artist
$result = mysql_query("SELECT * FROM members WHERE artistname= '$artistname'");
while($row = mysql_fetch_array($result)){
function spamcheck($field)
{
//filter_var() sanitizes the e-mail
//address using FILTER_SANITIZE_EMAIL
$field=filter_var($row['email'], FILTER_SANITIZE_EMAIL);
//filter_var() validates the e-mail
//address using FILTER_VALIDATE_EMAIL
if(filter_var($row['email'], FILTER_VALIDATE_EMAIL))
{
return TRUE;
}
else
{
return FALSE;
}
}
{//send email
$to = $row['email'];
$subject = "Congratulations! You're now an NBS artist";
$message = "Hi ".$row['artistname'].",
//message removed for condensed code
$from = "";
$headers = 'From:' . "\r\n" .
'Reply-To: ' . "\r\n";
mail($to,$subject,$message,$headers);
}
}
echo '<br><t1>You just made "'.$artistname.'" an artist! <b>Click here</b> to see their profile.</t1>';
}
}
}

You are missing two lines to convert the resource returned by mysql_query() into an integer for the comparison with 50.
$vote = mysql_query("SELECT vote FROM members WHERE artistname='$artistname'")or die(mysql_error());
// Add these two lines
$vote = mysql_fetch_assoc($vote);
$vote = $vote['vote'];
if ($vote > 50) {
...however, all that section could be re-written to use 2 queries instead of 4:
//make an artist if vote high enough
$artisturl = mysql_real_escape_string(htmlspecialchars(str_replace(' ', '',$_POST['artistname'])));
// This effectively combines the first SELECT and the two UPDATEs into one query
$result = mysql_query("
UPDATE members m
LEFT JOIN tracks t ON m.artistname = t.artistname
SET
m.artist = 'Y',
t.artist = 'Y',
m.image1 = '../files/noprofile.jpg',
m.artisturl = '$artisturl',
t.artisturl = '$artisturl'
WHERE m.artistname = '$artistname' AND m.vote > 50
") or die(mysql_error());
// If this affected more than 0 rows, the user was made an artist
if (mysql_affected_rows($result) > 0) {
//email user that has just been made artist
$result = mysql_query("SELECT * FROM members WHERE artistname= '$artistname'");
// ...and so on
Note also that you should pass data through mysql_real_escape_string() as the last operation. So it should go mysql_real_escape_string(htmlspecialchars($data)) rather than the other way around.

I'll throw a dart at this one.
$vote = mysql_query("SELECT vote FROM members WHERE artistname='$artistname'")or die(mysql_error());
if ($vote > 50) {
I don't believe you are converting your mysql_query result into a useful variable. Maybe you were using mysql_fetch_assoc or mysql_num_rows ? Num rows makes more sense if you have an individual record for each vote. If you are summing them up then you can use something like
$output = mysql_fetch_assoc(mysql_query("SELECT vote FROM members WHERE artistname='$artistname'")or die(mysql_error());
$vote = $output['vote'];
Something else to point out is that you aren't using mysql_real_escape_string on your inputs. This is very dangerous and it is strongly encouraged to use this function if you are facing the public internet.

Related

How to avoid exponential slowdown in PHP/MYSQL?

I'm the owner of an online browser based game that has around 300 players signed up. I've written a script to detect cheaters, but the issue is that the number of queries in said script will grow exponentially.
It works like this:
Send a query that gets player's information.
Inside of the query, run another query that gets the information of every player.
So basically I am running a query that gets every player's name and information, and inside of that query I run another query to get the information from every other player besides themself. I use this to compare and delete cheaters.
The issue is, since I have 300 players, I have to run 300 queries per player. That's 90,000 queries. If I reach 1,000 players, it would be 1,000,000 queries. There has to be a better way to do this.
My code:
<?php
require '../connect.php';
$rulerinfo = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password FROM players");
while ($rulerinfo2 = $rulerinfo->fetch_assoc()) {
$id = $rulerinfo2['id'];
$rulername = $rulerinfo2['rulername'];
$nationname = $rulerinfo2['nationname'];
$alliance = $rulerinfo2['alliance'];
$email = $rulerinfo2['email'];
$dateregister = $rulerinfo2['dateregister'];
$useragent = $rulerinfo2['user_agent'];
$lastseen = $rulerinfo2['lastseen'];
$password = $rulerinfo2['password'];
$playerinfo = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password FROM players WHERE id != '$id'");
while ($playerinfo2 = $playerinfo->fetch_assoc()) {
$id2 = $playerinfo2['id'];
$rulername2 = $playerinfo2['rulername'];
$nationname2 = $playerinfo2['nationname'];
$alliance2 = $playerinfo2['alliance'];
$email2 = $playerinfo2['email'];
$dateregister2 = $playerinfo2['dateregister'];
$useragent2 = $playerinfo2['user_agent'];
$lastseen2 = $playerinfo2['lastseen'];
$password2 = $playerinfo2['password'];
$rulerdistance = levenshtein($rulername, $rulername2);
$nationdistance = levenshtein($nationname, $nationname2);
$emaildistance = levenshtein($email, $email2);
$agentdistance = levenshtein($useragent, $useragent2) / 2;
$totaldistance = $rulerdistance + $nationdistance + $emaildistance + $agentdistance;
if ($password == $password2) {
$totaldistance = $totaldistance - 20;
}
if ($totaldistance < 0) {
$totaldistance = 0;
}
}
}
?>
You should only do the query once, put it in an array and work with it from there. I don't see the need to make almost the same query twice. Loop in your array a second time and just check if the id is not the same as the current.
$res = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password FROM players");
$array=array();
while ($row = $res->fetch_assoc()) {
$array[] = $row;
}
for($i=0; $i<count($array);$i++) {
for($j=0; $j<count($array); $j++) {
if ($i != $j) {
// Call your functions
$rulerdistance = levenshtein($array[$i]['rulername'], $array[$j]['rulername']);
...
}
}
}

getting number from php file with jquery ajax

I'm new to AJAX and jQuery. I'm trying to pass a number from unrate.php to be used as checkVal (as shown below). The file does a bunch of stuff but it only echos the number. When I add a alert(checkVal) it shows a invalid character and than the number I want. (I just want the number)...
ajax handler:
$.get("unrate.php?numb="+ID, function(checkVal){
if (checkVal == 1) {
number.innerHTML = addNumb + 1;
} else {
number.innerHTML = addNumb - 1;
}
});
unrate.php:
<?php
$uNum = $_SESSION['userNum'];
$ider = $_GET['numb'];
$sql = mysql_query("SELECT * FROM ratecheck WHERE ID =".$ider);
$checkRay = mysql_fetch_array($sql);
$checkVal = $checkRay[$uNum];
$sqlZ = mysql_query("UPDATE ratecheck SET `".$uNum."`=0 WHERE ID=".$ider)
or die(mysql_error());
$sqlB = mysql_query("SELECT * FROM sources WHERE ID =".$ider);
$sourceRay = mysql_fetch_array($sqlB);
$newRC = $sourceRay['ratecount'] - 1;
mysql_query("UPDATE sources SET ratecount =".$newRC." WHERE ID =".$ider)
or die(mysql_error());
if ($checkVal > 1)
{
$newpts = $sourceRay['points'] - 1;
$userEmail = $sourceRay['user'];
mysql_query("UPDATE sources SET points =".$newpts." WHERE ID =".$ider)
or die(mysql_error());
if ($_SESSION['userName'])
{
$findUser = mysql_query("SELECT * FROM users WHERE email LIKE '".$userEmail."'") or mysql_error();
$currentRate = mysql_fetch_array($findUser);
$newrating = $currentRate['rating'] - 1;
mysql_query("UPDATE users SET rating =".$newrating." WHERE email LIKE '".$userEmail."'")
or mysql_error();
}
else
{
die('ERROR');
}
}
else
{
$newpts = $sourceRay['points'] + 1;
$userEmail = $sourceRay['user'];
mysql_query("UPDATE sources SET points =".$newpts." WHERE ID =".$ider)
or die(mysql_error());
if ($_SESSION['userName'])
{
$findUser = mysql_query("SELECT * FROM users WHERE email LIKE '".$userEmail."'") or mysql_error();
$currentRate = mysql_fetch_array($findUser);
$newrating = $currentRate['rating'] + 1;
mysql_query("UPDATE users SET rating =".$newrating." WHERE email LIKE '".$userEmail."'")
or mysql_error();
}
else
{
die('ERROR');
}
}
echo $checkVal;
mysql_close();
?>
Extra characters at the beginning or end of your output are something you occasionally run into with php. I greatly endorse the comment that suggests looking at the raw output from the server. You might also want to think about these possibilities:
Invisible characters at the beginning or end of your script file. Use a text editor that will show you hidden characters (even a hex editor) and see if there are any. Also, you don't have to end your php script with ?> if you're not doing anything else past it. You can just leave it open, as that will prevent characters showing up at the end.
Check the character encoding that your script has. This might not be the solution, but some time ago I had a similar situation that went away when I changed the encoding to UTF8 without Byte-Order Mark. Try doing the same thing and see if that fixes it

Redirect A Certain Page if * Does not exist?

I have a profile.php page, and when someone views their own profile, it grabs the id of their user and adds profile.php?UserID=* (* being the id number of a user). At the moment, there is no legit way to look at others profiles, but you are able to change the id in the url. Problem is, you can go to the profile of a user who doesn't exist and make it will be the default profile page without anything on it. Is there a way to get the id from a page/url and see if it exists or not, and if not, to redirect to a certain page?
<?php
include('./dbnotseen/global.php');
$profile = mysql_query("SELECT * FROM admin WHERE username='$username'");
$row = mysql_fetch_array($profile);
$username = $row['username'];
if (($session_username)) {
}else {
("location: index.php");
}
//max per page
$per_page = 1;
//get start variable
$start = $_GET['UserID'];
//count records
$record_count = mysql_num_rows(mysql_query("SELECT * FROM admin"));
//count max pages
$mac_pages = $record_count / $per_page;
if (!$start)
$start = 0;
//display data
$get = mysql_query("SELECT * FROM admin WHERE id='$start'");
while ($row = mysql_fetch_array($get)) {
$id = $row['username'];
$picture = $row['picture'];
$admin = $row['admin'];
$status = $row['status'];
$desc = $row['description'];
$twitter = $row['twitter'];
}
?>
That's the main part of the PHP in the profile.php. The rest is just getting a status, description etc.
You can check if the result set of your mysql query is not empty. Doing it with mysql_ functions would look like so:
$get = mysql_query("SELECT * FROM admin WHERE id='$start'");
if (mysql_num_rows($get) > 0) {
while ($row = mysql_fetch_array($get)) {
// rest of your code
}
}
else {
// redirect to another page
header("Location: otherpage.php");
}
This would give you an idea on how you should approach it, but as #Madara Uchiha suggested in the comment to your question, you should stop using mysql_ functions.
A couple important things before solving your problem:
The MySQL_* family of functions has been deprecated and shouldn't be used anymore.
Your code is vulnerable to a huge security hole - SQL Injection. Please make sure you're sanitizing your database queries - if nothing else, with just $start = mysql_real_escape_string($_GET['UserID']); in your current code.
Now, it looks like you want to check and see how many results you get back for your $get query. You could just use the mysql_num_rows function:
if (!mysql_num_rows($get)) {
//no user exists! do something different here
} else {
while ($row = mysql_fetch_array($get)) {
$id = $row['username'];
$picture = $row['picture'];
$admin = $row['admin'];
$status = $row['status'];
$desc = $row['description'];
$twitter = $row['twitter'];
}
}
You can also count the records in the admin table matching criteria id = $start with the following SQL statement:
"SELECT COUNT(*) FROM admin WHERE id='$start'"
If there are no matching records, then the provided UserID doesn't belong to any user and you should probably redirect the user to some page explaining what went wrong.

table updates empty spaces when user do not enter anything to the textbox

i am doing a project where one may update the name, position, department and tag of the employee.
But as i do my project, it wont update, i know there is something wrong with my code. would you guys mind checking it.
my php page has an index.php which is the main menu, if you click the employee name in the list, a pop up window will appear. that pop up is for updating.
my php code (it now updating) but errors found:
<?php
$con=mysql_connect('localhost','root','pss') or die(mysql_error());
mysql_select_db('intra',$con);
if(isset($_POST['submitted']))
{
$sql = "SELECT * FROM gpl_employees_list where emp_id='".$_POST['eid']."'";
$result = mysql_query($sql) or die (mysql_error());
if(!$result || mysql_num_rows($result) <= 0)
{
return false;
}
$qry = "UPDATE gpl_employees_list SET emp_nme = '".$_POST['ename']."', emp_pos = '".$_POST['pos']."', emp_dep = '".$_POST['dep']."', emp_tag = '".$_POST['tag']."' WHERE emp_id = '".$_POST['eid']."' ";
mysql_query($qry) or die (mysql_error());
?><script>window.close();</script><?php
}
?>
*NOTE : this is now updating, but if a user leaves one of the textboxes empty, it updates the table with empty spaces as well and that is my problem now. how do i avoid that? i mean if a user leaves one textbox empty,the data with empty values must still contain its old value,but how to do that with this code? thanks for those who will help
MisaChan
You use $_POST for 'name/pos/dep/tag' and $_GET for 'emp' so you're probably not getting the values.
Change the GETs to POST - that should do it.
Since you're updating, I'd recommend using POST over GET.
GET is more appropriate for searching.
Also, you can put all your update queries into one update query.
Like so.
$name = $_POST['name'];
$pos = $_POST['pos'];
$dep = $_POST['dep'];
$tag = $_POST['tag'];
$emp = $_POST['emp'];
$qry_start = "UPDATE gpl_employees_list SET ";
$where = " WHERE emp_id = $emp";
$fields = "";
$updates = "";
if($name){
$updates .= " `emp_name` = $name,";
}
if($pos){
$updates .= " `emp_pos` = $pos,";
}
if($dep){
$updates .= " `emp_dep` = $dep,";
}
if($tag){
$updates .= " `emp_tag` = $tag,";
}
$updates = substr($updates, 0, -1); //To get rid of the trailing comma.
$qry = $qry_start . $updates . $where;
this is what i used to keep it working :) i hope this could be a source for others as well :)
$col['emp_nme'] = (trim($_POST['ename']))?trim($_POST['ename']):false;
$col['emp_pos'] = (trim($_POST['pos']))?trim($_POST['pos']):false;
$col['emp_dep'] = (trim($_POST['dep']))?trim($_POST['dep']):false;
$col['emp_tag'] = (trim($_POST['tag']))?trim($_POST['tag']):false;
// add a val in $col[] with key=column name for each corresponding $_POST val
$queryString ="UPDATE `gpl_employees_list` SET ";
foreach($col as $key => $val){
if($val){
$queryString .="`".$key."`='".$val."',";
}
}
$queryString = substr($queryString ,0 ,strlen($queryString) - 1 )." WHERE emp_id = '".$_POST['eid']."'";
mysql_query($queryString);
After making changes to an SQL database, remember to commit those changes, otherwise they'll be ignored.

php check duplicate email string

I've got small problem checking the duplicate email, I don't know what I've done wrong.
PHP SIDE:
// convert to lower case
$email = $db->real_escape_string(trim(strtolower($_POST['email'])));
$q = $db->query("SELECT email FROM user WHERE email='$email'");
$r = $q->fetch_assoc();
if($email == $r['email']) {
echo 'yes';
} else {
echo 'no';
}
I've got an old record in the database. Some of the emails come mixed with uppercase and lowercase! And most of them are from hotmail email account! How to check email that even contain lower and uppercase?
ie: Donald1990#hotmail.com // it skips the duplicate error?
Hedmunds#hotmail.co.uk
hedmunds#hotmail.co.uk
Actually I think you want
"SELECT LOWER(email) FROM user WHERE LOWER(email)='$email'"
i am using laravel 5, but the concept is same
//check from 1 to 500 records, some DB will timeout if 1 to 5000 or more depends on amount of Data, you may have to increase the timeout limit
$users = Subscribers::all(); // take all users from DB
for ($x = $check_from; $x <= $check_to; $x++){
$check_user = Subscribers::select('id','email')->where('id',$x)->first();
if (!isset($check_user)){ // check for gaps in betw records
echo $x . "- not set<br>";
}
else{
$check_user_id = strtolower(trim($check_user->id));
$check_user_email = strtolower(trim($check_user->email));
foreach ($users as $user){
$user_id = strtolower(trim($user->id));
$user_email = strtolower(trim($user->email));
if ($check_user_email == $user_email AND $check_user_id !== $user_id ){
echo $check_user_id.' - '.$user_id.' - '. $user_email.' - Duplicated records<br>';
//$user->delete();
// choose to delete duplicate or whatever u wanna do with it
}
}
}
}
// need to check email is equal && user_id is not same, then there will be 2 id with same email
My code works but if someone can improve to make it shorter will be better.

Categories