I am new to php so far i wrote this referral script:
<?php
ob_start();
include( $_SERVER['DOCUMENT_ROOT'] . '/config.php' );
mysql_connect(DB_HOST,DB_USER,DB_PASS);
mysql_select_db(DB_NAME);
$id = $_REQUEST['id'];
$uid = $_REQUEST['uid'];
$oid = $_REQUEST['oid'];
$new = $_REQUEST['new'];
$total = $_REQUEST['total'];
$sig = $_REQUEST['sig'];
// Secrete Key
$hash = 'myapikey';
// Output results
if ($sig == $hash) {
//Users point update query here (it's working )
$users = mysql_query("SELECT points FROM users WHERE id=".$uid);
$rows = mysql_fetch_array($users);
$user_points = $rows['points'];
$query1 = mysql_query("update users set points=($user_points+$new) where id=".$uid );
//Updating referral coins (it's not working )
$query2 = ("SELECT points, referral_id, level FROM users WHERE referral_id=".$uid );
$user_rows = mysql_query($query2);
$all=mysql_fetch_array($user_rows,MYSQL_BOTH);
if($all['referral_id'] != 0 && $all['level'] == 0){
$lvl0 = $new*(15/100);
$referal_points = $lvl0;
$update_referral_points = ("update users set points = points + $referal_points where referral_id = ".$all['referral_id']);
mysql_query($update_referral_points);
} else if($all['referral_id'] != 0 && $all['level'] == 1){
$lvl1 = $new*(25/100);
$referal_points = $lvl1;
$update_referral_points = ("update users set points = points + $referal_points where referral_id = ".$all['referral_id']);
mysql_query($update_referral_points);
}
print "1\n";
} else {
print "0\n";
}
?>
How Script working:
whenever someone signup using referral code i have insert referral code user id into new user referral_id row, & through $_REQUEST['']; my app sending points ($new) to user...
$query1 is working fine there's problem to execute $query2, in short $query2 needs to be fixed; something getting wrong, that i am not able to figure out if any pro can help me out this i will appreciate it...
DB structure:
users table:
id (AI) name points Referral code Referral id Level
=========== ========== ========== ================== ============== ======
1 user A 0 abcdef123 0 0
2 user B 100 bvsuda897 1 1
3 user C 500 vrtasio65 2 0
In this example above,
1- user C signup using user B Referral code = bvsuda897
2- right now user B level is 1 so whenever user C earn point ($new) my app should give user B 25% coins of user C $new
The Problem
right now when my app sending coins to user C, user B not getting coins, because something wrong in query2
After spending some more time looking over your code, I have tracked down your issue. First, you need to get the referral_id from the $users query.
$users = mysql_query("SELECT points, referral_id FROM users WHERE id=".$uid);
Then $query2 needs to match the id to the user's referral_id, not the other way around.
$query2 = "SELECT id, points, referral_id, level FROM users WHERE id=".$rows['referral_id'];
Your UPDATE queries may need some work after that, but this will get you in to the if else conditions.
Successful code determined by OP
//Updating referral coins
$query2 = "SELECT id, points, referral_id, level FROM users WHERE id=".$rows['referral_id']; $user_rows = mysql_query($query2);
$all=mysql_fetch_array($user_rows,MYSQL_BOTH);
$lvl0 = intval((5/100) * $new);
$lvl1 = intval((10/100) * $new);
$query3 = mysql_query("update users set points = (points + $lvl0) where level = 0 AND referral_id = ".$all['referral_id']);
$query4 = mysql_query("update users set points = (points + $lvl1) where level = 1 AND referral_id = ".$all['referral_id']);
Now I appreciate that you are in the learning stage, but I want to point out a couple things that will cause confusions as you pursue PHP programming in the future.
First off, as Option mentioned, the MySQL functions you are using have been deprecated. They do not exist in the current stable version of PHP, and your code will no longer work if the server is updated. Look in to MySQLi or PDO as alternatives. It's a lot to learn, but some Googling will get you some guidance.
Second is your use of $_REQUEST, which combines the values of $_GET, $_POST and $_COOKIE, allowing easy manipulation by visitors. It may be that you are only using it for the user details while testing your other code, but I just want to make sure you know about PHP sessions, which is the better way to store a relationship between a logged in user and their persistent variables.
Related
I am new to php and the mvc structure, however I am developing a library app for personal development. All is working as expected however I would like to implement one more feature - 'favourites'.
A notifications style bar contained within a <div>.
I currently have a favourites table that contains the following;
id book_id user_id
1 2422 22
2 6551 71
3 7716 22
What I am trying to do is simply display to the logged in user (eg user 22 above) "Hello, you have 2 items in your favourites". I know this should be relatively simple and it would normally be, however the mvc format has me slightly confused.
I think I have the bulk of the work done I just need some direction and advice as to where I am going wrong. Is there something else I should be loading or including? How should I display the number of favourites within the <div>?
I have included my code below for reference.
books_controller.php
function checkFav()
{
$checkFav_model = $this->loadModel('Books');
$checkFav_model->wishList();
}
function itemView()
{
$itemView_model = $this->loadModel('Books');
$this->view->books = $itemView_model->itemView();
$this->view->render('books/itemView');
}
books_model.php
public function wishList()
{
$userid=$_SESSION['user_id'];
$sql = "SELECT COUNT(*) FROM favourite WHERE user_id = :user_id";
$query = $this->db->prepare($sql);
$query->bindParam(':user_id', $userid);
$query->execute();
$rows_found = $query->fetchColumn();//numRows doesnt work
if(empty($rows_found)) {
echo $rows_found;
} else {
echo $rows_found;
}
}
header.php
<div class="notifications">
**DISPLAY NUMBER OF FAVS HERE**
</div>
Try this query:
$sql = "SELECT COUNT(book_id) AS book FROM favourite WHERE user_id = :user_id";
Reason : User has many favorite book. And your quote adbove
"Hello, you have 2 items in your favourites"
so i think you want to showing how much book he likes. Not how many times he liked the book. But it can be done to with SUM on user_id.
Hmm maybe this way:
$sql = "SELECT COUNT(id) as count FROM favourite WHERE user_id = :user_id";
$query = $this->db->prepare($sql);
$query->bindParam(':user_id', $userid);
$query->execute();
$rows_found = $query->fetchAll();
$rows_found = $rows_found[0][count];
I have this script as a cron job set to run every 5 mins, the problem is it will not increment the energy level as I believe it should. If anyone can tell me what I am doing wrong here it would be great.
Remember, this returns no errors, just doesn't work, also the database connect info is all correct, just left out of the post.
{
$energy = mysql_query("SELECT energy FROM members WHERE id=$id");
//get current users energy level
$energy_max = mysql_query("SELECT energy-Max FROM members WHERE id=$id");
//get current users Maximum energy level
if ($energy < $energy_max)
// do -if current energy level is less than maximum
{
$energy = $energy ++;
//increment energy by 1
mysql_query("UPDATE members SET energy= $energy");
//set the new energy level
}
$id++;
//increment to the next user
}
You can solve everything within a single statement
UPDATE `members` SET `energy` = `energy` + 1 WHERE `energy-Max` > `energy`;
This way you have one instead of 3 * number-of-members queries
You forgot the WHERE id = $id in the update Statement.
mysql_query("UPDATE members SET energy= $energy WHERE id = $id");
But KingCrunch's answer is better ..
mysql_query doesn't return values, only so-called query id. You have to fetch actual data:
$query = mysql_query("SELECT energy FROM members WHERE id=$id");
$val = mysql_fetch_assoc($query); // Now the data is in $val['energy']
Of course you can do this quicker, via this (as pointed in other answer):
UPDATE members SET energy = energy + 1 WHERE energy < energy-Max;
I manage a rather large traffic website. On each page we keep track of a visitors online by running the following code. We then have a cron which deletes the records which are older than X minutes.
if(!isset($_SESSION[users_online_id])) {
if(!(date('H')=='02' && date("i") >= 37 && date("i") <= 45)) {
# NEW VISITOR - DOESN'T HAVE A USER_ONLINE_ID
$update_query = "INSERT INTO online SET
ip_address = '".$visitors_ip_address."',
datetime = now(),
user_id = ".$visitor_id.",
page = '".escape($_SERVER[REQUEST_URI])."',
area = '".$this_area."',
type = ".$visitor_type;
mysql_query($update_query);
# SET THEIR SESSION VAR FOR NEXT PAGE CHECKING
$_SESSION[users_online_id] = mysql_insert_id();
}
}
else{
# USER HAS A SESSION
# CHECK THAT THE RECORD STILL EXIST
$check_record = "SELECT COUNT(1) FROM online WHERE id = ".$_SESSION[users_online_id];
$check_record = mysql_query($check_record);
if(mysql_result($check_record,0) > 0){
# IF RECORD STILL EXISIT ( WAS NOT DELETED) UPDATE IT
$update_query = "UPDATE online SET
datetime = now(),
user_id = ".$visitor_id.",
page = '".escape($_SERVER[REQUEST_URI])."',
type = '".$visitor_type."',
area = '".$this_area."',
ip_address= '".$visitors_ip_address."'
WHERE id = '".$_SESSION[users_online_id]."'";
mysql_query($update_query);
}
else if(!(date('H')=='02' && date("i") >= 37 && date("i") <= 45)){
# IF RECORD WAS DELETED (TO LONG ON 1 PAGE), INSERT A NEW RECORD
$update_query = "INSERT INTO online SET
ip_address = '".$visitors_ip_address."',
datetime = now(),
user_id = ".$visitor_id.",
page = '".escape($_SERVER[REQUEST_URI])."',
area = '".$this_area."',
type = ".$visitor_type;
mysql_query($update_query);
$_SESSION[users_online_id] = mysql_insert_id();
}
}
Doing some performace monitoring, i have noticed that queries which interact with this table are starting to take a lot longer to execute. Any ideas on how this can be improved?
You may eliminate SELECT query and use UPDATE query and mysql_affected_rows() function.
Small point but...
$_SERVER['REQUEST_URI'] is 7x faster than $_SERVER[REQUEST_URI]
Also make sure id is set up as the primary key.
I have created a lottery script in php. My problem is now selecting more then one winner. Because it is possible for players to have the same number on their tickets. Here I am supplying the two table structures and the source code.
lotto_game {
id(int)
jackpot(int)
status(varchar10)
pick_1(int)
pick_2(int)
pick_3(int)
pick_4(int)
pick_5(int)
tickets_sold(int)
winner(text)
}
lotto_picks {
lotto_id(int)
user_id(int)
choice_1(int)
choice_2(int)
choice_3(int)
choice_4(int)
choice_5(int)
ticket_status(int)
}
These are my two tables with in my database. For examples sake we will create 2 users with the id's 1, and 2. So what happens is when the script runs it is suppose to change the lotto_game status from 'active' to 'finished' then add the random lottery numbers into each pick_* column.
$one = rand(1,30);
$two = rand(1,30);
$three = rand(1,30);
$four = rand(1,30);
$five = rand(1,30);
mysql_query("UPDATE `lotto_game` SET
pick_1 = '$one',
pick_2 = '$two',
pick_3 = '$three',
pick_4 = '$four',
pick_5 = '$five',
status = 'finished'
WHERE status = 'active'");
That wasn't too hard I will admit. But this is just the beginning of the end.
$lotto['tickets'] = mysql_query("SELECT ticket_id FROM `lotto_picks` WHERE ticket_status='valid'");
#$lotto[winners] = mysql_query("SELECT ticket_id,user_id FROM `lotto_picks` WHERE choice_1 = '$one' AND choice_2 = '$two' AND choice_3 = '$three' AND choice_4 = '$four' AND choice_5 = '$five'");
$lotto['num_tickets'] = mysql_num_rows($lotto['tickets']);
#$lotto[winner_id] = mysql_fetch_array(#$lotto[winners]);
$lotto['jackpot'] = mysql_query("SELECT jackpot FROM `lotto_game` WHERE status='active'");
$lotto['winner_jackpot'] = mysql_fetch_array($lotto['jackpot']);
$lotto['num_winners'] = mysql_num_rows($lotto['winners']);
//echo #$lotto['num_tickets'];
//echo #$lotto['num_winners'];
$winner = $lotto['num_winners'];
//echo #$lotto['winner_id']['user_id'];
$jackpot = $lotto['winner_jackpot']['jackpot'];
$id = #$lotto[winner_id][user_id];
if ($winner == 1) {
mysql_query("UPDATE `character` SET
decivers = decivers +'$jackpot'
WHERE user_id='$id'");
}
This is what I have come up with and it really seems to work with one winner. But I just cant figure out where to go from here. I have tried using some arrays but nothing works. I know what needs to be done but can't figure out how to do it.
When I search for winners I need to put into an array all their user id's.
so extra decivers is money, if anyone is confused on that. The status on the tickets doesn't really matter here but if you must know it just determines if the ticket_status is 'valid' or 'invalid'
i think you've chosen the wrong storage formats for your picked numbers. The standard approach is to use binary values which have N-th bit set if the number N is choosen.
Consider this example: user chooses numbers "2 4 5 9 11". Setting corresponding bits to 1 gives '10100011010' which is decimal 1306. Now the lottery picks "4 7 9 12 13" which is '1100101001000' == 6472. Perform a bitwise AND on both values and count the number of bits set in the result:
SELECT BIT_COUNT(1306 & 6472)
this immediately tells us that the user has 2 correct picks. Just as easy you can select "full" winners:
SELECT * FROM tickets WHERE BIT_COUNT(tickets.pick & lotto.pick) = 5
or sort the tickets by the number of correct picks
SELECT * FROM tickets ORDER BY BIT_COUNT(tickets.pick & lotto.pick) DESC
$winners_array = array();
if(mysql_num_rows($lotto['winners'])!=0){
while($row =mysql_fetch_array($lotto['winners'])){
if(!in_array($row['user_id'],$winners)) $winners[] = $row['user_id'];
}
}
$winners will be an array with all the winners user_ids
I'm wondering if this is the best way to tackle this issue. I am merging a Facebook users friends data, (from facebook - returns a multi array) with the votes from the users in that list that voted (from MySQL).
This is how I accomplished this. I'm a junior developer and looking for help on making my code as optimized as possible.
public function getFriendVotes(){
global $facebook;
// Get The users friends that use this app from facebook
$friends = $facebook->api_client->fql_query(
"SELECT uid, first_name, last_name
FROM user
WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user)"
);
// Create an array of just the ids
foreach($friends as $friend){
$userids[] = $friend['uid'];
}
// Create a string of these ids
$idstring = implode(",", $userids);
// Get the votes from only the users in that list that voted
$result = $this->db->query(
"SELECT vote, userid FROM user_votes WHERE userid IN ($idstring)"
);
// Create a new result set (multi array). Include the data from the first
// Facebook query, but include only those who voted and append their votes
// to the data
$row = $result->fetch_assoc();
foreach($friends as $friend){
if($row['userid'] == $friend['uid']){
$return[$count] = $friend;
$return[$count]['vote'] = $row['vote'];
$row = $result->fetch_assoc();
$count++;
}
}
return $return;
}
I asume that fql_query does support mysql syntax and it would be more efficient to use LEFT JOIN instead creatig extra query, here is my version of your code:
public function getFriendVotes(){
global $facebook;
// Get The users friends that use this app from facebook
$friends = $facebook->api_client->fql_query("
SELECT DISTINCT u.uid,u.first_name,u.last_name
FROM user AS u
LEFT JOIN friend AS f ON uid=uid2
WHERE f.uid1='{$this->user}'
");
$arrayUsers = array();
// Create an array of just the ids
foreach($friends as $v){
$arrayUsers[$friend['uid']] = $v;
}
unset($friends);
// Create a string of these ids
$idstring = implode(",", array_keys($arrayUsers));
// Get the votes from only the users in that list that voted
$result = $this->db->query(
"SELECT vote, userid FROM user_votes WHERE userid IN ({$idstring})"
);
$result = array();
// Create a new result set (multi array). Include the data from the first
// Facebook query, but include only those who voted and append their votes
// to the data
while($v = $result->fetch_assoc())
{
if(isset($arrayUsers[$v['userid']])
{
$arrayUsers[$v['userid']] = $v['vote'];
$result[] = $arrayUsers[$v['userid']];
unset($arrayUsers[$v['userid']], $v);
}
}
return $return;
}
I can't tell you how your code would perform without measuring and testing. I would look for other issues with your code, that would make it a bit more readable/maintanable. For example:
Create smaller methods.
Inside the main method , I see some chunks of code that are well commented. Why not create a method instead of making a huge comment in the main method?
For example:
// Get The users friends that use this app from facebook
$friends = $facebook->api_client->fql_query(
"SELECT uid, first_name, last_name
FROM user
WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user"
);
return $friends;
Would make an interesting
functin get_users_friends_from_facebook($facebook){
// Get The users friends that use this app from facebook
$friends = $facebook->api_client->fql_query(
"SELECT uid, first_name, last_name
FROM user
WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user"
);
return $friends;
}
In the same manner,
// Get the votes from only the users in that list that voted
$result = $this->db->query(
"SELECT vote, userid FROM user_votes WHERE userid IN ($idstring)"
);
Is a good candidate to
function get_votes_from_voters(){
// Get the votes from only the users in that list that voted
$votes = $this->db->query(
"SELECT vote, userid FROM user_votes WHERE userid IN ($idstring)"
);
}
Give variables meaningful names to the context.
$return isn't a good name. Why don't you name it $users_votes for example?
Try to keep the naming convention of your plataform.
Check the apis you're using. Are they using camelCase? Are they using underscores? Try to keep with your libraries and plataform conventions. Check this topic for a good reference.
And welcome to SO. Your code is fine. Try to read some OO principles, you could even cut more lines of your code. All the simple advices I wrote here are avaiable in a great book named Code Complete.
I took points from all your comments and rewrote this method as below. Thanks for all the great input.
public function getAppUserFriends(){
global $facebook;
return $facebook->api_client->fql_query(
"SELECT uid, first_name, last_name
FROM user
WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user)
AND is_app_user;"
);
}
public function getFriendVotes(){
// Get the users friends that use this app
$friends = $this->getAppUserFriends();
// Create an array with the ids as the key
foreach($friends as $v){
$arrayFriends[$v['uid']] = $v;
}
// Create a string of these ids
$idString = implode(",", array_keys($arrayFriends));
// Get the votes from only the users in that list that voted
$result = $this->db->query(
"SELECT vote, userid
FROM user_votes
WHERE pollid=$this->poll
AND userid IN ($idString)"
);
// Pluck out user data from facebook array where the user has voted
// and add the vote to that array
while($row = $result->fetch_assoc()){
$friendsVotes[$row['userid']] = $arrayFriends[$row['userid']];
$friendsVotes[$row['userid']]['vote'] = $row['vote'];
}
return $friendsVotes;
}
Are you having performance troubles in this method? Because unless you are, there's no need to optimize it.
Code first, profile the code, and then optimize where it does the most good.
$friends = $facebook->api_client->fql_query(
"SELECT uid, first_name, last_name
FROM user
WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user"
);
could probably be shortened to
$userids = $facebook->api_client->fql_query(
"SELECT uid
FROM user
WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user)"
);
because the uid is the only thing you seem to be using from fb
It was a little hard for me to tell what you are trying to do, but you might consider looking at PHP's array_intersect (and its cousins).
A = {1:'fred', 2:'bob'}
B = {1: 2, 3: 0}
C = array_intersect( array_keys(A), array_keys(B) )
D = {}
foreach (C as c) {
D[c] = (A[c], B[c])
}
The syntax is off there but I hope it leads you in the right direction.