-
Posts
827 -
Joined
-
Last visited
-
Days Won
9
Everything posted by fastsol
-
What kind of information are you storing that you need to encrypt only to decrypt to show it to the same person that gave it to you? Some more details from you would give us a better comprehension of your goal and how to advise you.
-
PayPal IPN getting payment status and other values
fastsol replied to seany123's topic in PHP Coding Help
In my opinion, you don't need both the api and the ipn, it's one or the other depending on your system. With the api all of the transaction is taken care of right then, you can update and do whatever you want in the db at that time. With the ipn, you need to wait for paypal to send the ipn and then update the db. Also with the ipn way, paypal doesn't redirect back immediately after the transaction, whereas the api redirects back as soon as paypal secures the payment on your behalf so you can finish the payment on your site. The new api is really the better way to go about taking payments on your website, I only used the ipn cause the other older versions of things they had were far to complicated to integrate easily, unlike the new api which is far easier now. -
I have implemented a custom error handling and it logs the errors to a DB with the standard file name, line number, code number and error string. But I can't find anything on how to get the full call stack that lead to the error. Maybe it's not possible using set_error_handler(). I'm also using register_shutdown_function() to catch fatal errors, but same situation with the call stack. So can I get the call stack/stack trace whatever?
-
No, that's not a valid url string. You would do this and return that image from the script. <img src="track.php?id=123&image=logo.jpg" >
-
PayPal IPN getting payment status and other values
fastsol replied to seany123's topic in PHP Coding Help
Here is the basic script that paypal provides for the ipn service. <?php //reading raw POST data from input stream. reading pot data from $_POST may cause serialization issues since POST data may contain arrays $raw_post_data = file_get_contents('php://input'); $raw_post_array = explode('&', $raw_post_data); $myPost = array(); foreach ($raw_post_array as $keyval) { $keyval = explode ('=', $keyval); if (count($keyval) == 2) $myPost[$keyval[0]] = urldecode($keyval[1]); } // read the post from PayPal system and add 'cmd' $req = 'cmd=_notify-validate'; if(function_exists('get_magic_quotes_gpc')) { $get_magic_quotes_exits = true; } foreach ($myPost as $key => $value) { if($get_magic_quotes_exits == true && get_magic_quotes_gpc() == 1) { $value = urlencode(stripslashes($value)); } else { $value = urlencode($value); } $req .= "&$key=$value"; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://www.paypal.com/cgi-bin/webscr'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_POSTFIELDS, $req); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: www.paypal.com')); // In wamp like environment where the root authority certificate doesn't comes in the bundle, you need // to download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path // of the certificate as shown below. // curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); $res = curl_exec($ch); curl_close($ch); // assign posted variables to local variables //$item_name = htmlentities($_POST['item_name_1']); //$item_number = (int)$_POST['item_number_1']; if (strcmp ($res, "VERIFIED") == 0) { // check the payment_status is Completed // check that txn_id has not been previously processed // check that receiver_email is your Primary PayPal email // check that payment_amount/payment_currency are correct // process payment } else if (strcmp ($res, "INVALID") == 0) { // log for manual investigation } ?> You then go into your paypal account and turn on ipn service and provide the full url path to your ipn processing script. I can tell you from experience that making sure your script works properly can be tricky since your can't really see the errors it throws when ran cause it's called from paypals side. I started by making a simple db table to hold the full posted results from paypal so I could see what they send back and how it was named. foreach($_POST as $k => $v) { $value.= $k.' / '.$v.', '; } $set = $db->prepare("INSERT INTO `test` SET `posted_values` = ?"); $set->execute(array($value)); Then to do my own testing based on the posted info I made another script that puts all the info into a form with text fields so I could repeatedly post the info and test additional query stuff or processing stuff. <?php // This list needs to be coppied from the posted text in the table paypal posted to in the other script I showed you. $test = 'mc_gross / 65.00, protection_eligibility / Eligible, address_status / confirmed, item_number1 / 14, payer_id / KP3ZSMAGVU764, tax / 0.00, address_street / 3415 Delaware Dr., payment_date / 15:22:41 Mar 04 2014 PST, payment_status / Completed, charset / windows-1252, address_zip / 29040, mc_shipping / 0.00, mc_handling / 0.00, first_name / kevin, mc_fee / 2.19, address_country_code / US, address_name / kevin korstange, notify_version / 3.7, custom / 0::standard::c, payer_status / unverified, business / [email protected], address_country / United States, num_cart_items / 1, mc_handling1 / 0.00, address_city / Dalzell, verify_sign / AFcWxV21C7fd0v3bYYYRCpSSRl31AQ50RA-5fQQNKQEAtVOK-KdptSAk, payer_email / [email protected], mc_shipping1 / 0.00, tax1 / 0.00, txn_id / 8JV23519RC589220L, payment_type / instant, last_name / korstange, address_state / SC, item_name1 / CWP Certification Course - 3/15/2014, receiver_email / [email protected], payment_fee / 2.19, quantity1 / 1, receiver_id / UK6DJWQC3AXBE, txn_type / cart, mc_gross_1 / 65.00, mc_currency / USD, residence_country / US, transaction_subject / 0::standard::c, payment_gross / 65.00, ipn_track_id / 1d2ea5b3bcfad'; if(isset($_POST['submit'])) { print_r($_POST); } ?> <div style="width:350px; text-align: right"> <form action="" method="post"> <?php $item = explode(",", $test); echo '<input type="submit" name="submit" value="submit"><br>'; foreach($item as $i) { $ex = explode(" / ", $i); echo trim($ex[0]).' <input type="text" name="'.trim($ex[0]).'" value="'.$ex[1].'"><br>'."\n"; //$ex[] = explode(" / ", $i); } $op_array = array(); foreach($item as $i) { $ex = explode(" / ", $i); //echo $ex[0].' - '.$ex[1].'<br>'; } echo ''; ?> <input type="submit" name="submit" value="submit"> </form> </div> Be aware though, at least cause of how I stored the info and how I explode it, the "address_street /" in the $test usually contains a "," in the value part. I usually just delete the last half of the address since that's not really the data you need to deal with anyway, otherwise the explode will give you unexpected results and the input names won't match up right. Here is what one of my full ipn scripts looks like. <?php require_once($_SERVER['DOCUMENT_ROOT'].'/site_req/core.php'); require_once(ROOT.'site_inc/system_inc/includes.php'); //reading raw POST data from input stream. reading pot data from $_POST may cause serialization issues since POST data may contain arrays $raw_post_data = file_get_contents('php://input'); $raw_post_array = explode('&', $raw_post_data); $myPost = array(); foreach ($raw_post_array as $keyval) { $keyval = explode ('=', $keyval); if (count($keyval) == 2) $myPost[$keyval[0]] = urldecode($keyval[1]); } // read the post from PayPal system and add 'cmd' $req = 'cmd=_notify-validate'; if(function_exists('get_magic_quotes_gpc')) { $get_magic_quotes_exits = true; } foreach ($myPost as $key => $value) { if($get_magic_quotes_exits == true && get_magic_quotes_gpc() == 1) { $value = urlencode(stripslashes($value)); } else { $value = urlencode($value); } $req .= "&$key=$value"; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://www.paypal.com/cgi-bin/webscr'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_POSTFIELDS, $req); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: www.paypal.com')); // In wamp like environment where the root authority certificate doesn't comes in the bundle, you need // to download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path // of the certificate as shown below. // curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); $res = curl_exec($ch); curl_close($ch); // assign posted variables to local variables //$item_name = sanitize($_POST['item_name_1']); //$item_number = (int)$_POST['item_number_1']; if(isset($_POST['item_name_1'])){ $item_name = sanitize($_POST['item_name_1']); } elseif(isset($_POST['item_name1'])){ $item_name = sanitize($_POST['item_name1']); } elseif(isset($_POST['item_name'])){ $item_name = sanitize($_POST['item_name']); } if(isset($_POST['item_number_1'])){ $item_number = (int)$_POST['item_number_1']; } elseif(isset($_POST['item_number1'])){ $item_number = (int)$_POST['item_number1']; } elseif(isset($_POST['item_number'])){ $item_number = (int)$_POST['item_number']; } else{$item_number = '';} $payment_status = $_POST['payment_status']; $payment_amount = (float)$_POST['mc_gross']; $payment_currency = $_POST['mc_currency']; $txn_id = sanitize($_POST['txn_id']); $receiver_email = $_POST['receiver_email']; $payer_email = $_POST['payer_email']; $product_id = (int)$_POST['custom']; if (strcmp ($res, "VERIFIED") == 0) { // check the payment_status is Completed // check that txn_id has not been previously processed // check that receiver_email is your Primary PayPal email // check that payment_amount/payment_currency are correct // process payment $bad = FALSE; if($payment_status != 'Completed'){ $bad = TRUE; $what='status';} if(checkDepositTxn($txn_id) === TRUE) { $bad = TRUE; $what='txn';} if($receiver_email != Settings::get('paypal_email')) { $bad = TRUE; $what='email';} //if($payment_amount != '20.00') { $bad = TRUE; $what='amount';} if($payment_currency != 'USD') { $bad = TRUE; $what='currency';} if(empty($item_number)){ $bad = TRUE; $what = 'other charge'; } $db = DB::getInstance(); if($bad === FALSE) { //Process payment stats $now = time(); $set = $db->prepare("INSERT INTO `".QUOTE_DEPOSITS."` SET `txn_id`= ?, `q_id`='$item_number', `part_num`= ?, `dep_date`='$now', `product_id`=$product_id, `deposit_amount`=$payment_amount"); $set->execute(array($txn_id, $item_name)); //$db->query("UPDATE `".QUOTE_RESPONSES."` SET `purchased`=1 WHERE `id`='$item_number'"); } elseif($bad === TRUE && $what != 'other charge') { $valu=''; foreach($_POST as $k => $v) { $valu.= $k.' / '.$v.', '; } $valu = sanitize($valu); $set2 = $db->prepare("INSERT INTO `".QUOTE_DEPOSITS."` SET `why` = ?, `params` = ?"); $set2->execute(array($what, $valu)); } } else if (strcmp ($res, "INVALID") == 0) { // log for manual investigation } ?> I have another that my cms uses that is much longer. And no you can't use 2 different ipn scripts, I have this one as a special use for a particular site, whereas my cms script is used in typical cases. Hope that helps get you started. NOTE: the code I posted to test the values sent by paypal was pieced together on this post since the whole script contains other stuff that was specific to my site and would only confuse anyone else using it so I removed those parts. So that code is untested as it sits on this post, maybe syntax errors if I missed something in the piecing together. -
Why in the world are you wrapping a form in a <a>? That is certainly not how it works. Are you trying to display an image when you click? You haven't really given us a clear understanding of what you are trying to do and what kind of file it's supposed to serve.
-
In the img src tag you put a file name of a script on your server that serves the image and runs a query when it's called by the img src in the email.
-
PayPal IPN getting payment status and other values
fastsol replied to seany123's topic in PHP Coding Help
You're confusing the 2 concepts between the tutorial and what IPN is. -
PayPal IPN getting payment status and other values
fastsol replied to seany123's topic in PHP Coding Help
No the IPN doesn't redirect, paypal redirects and then paypal sends a separate POST to the IPN file you list inside your actual paypal account. The tutorial does not have anything to do with IPN. Like I said, I'm pretty sure that the new api doesn't handle anything with IPN, that's something totally different. -
PayPal IPN getting payment status and other values
fastsol replied to seany123's topic in PHP Coding Help
I have not used the new paypal api as of yet, but understand it a little. The IPN service i don't think is really part of the api. IPN is a separate thing that paypal does on it's own AFTER a transaction has happened on THEIR site. I use the IPN for my business so I know how it works not using the api anyway. I have considered switching to the new api stuff as it seems easier to understand and gives a certainly faster response of the transaction than the classic IPN does. The IPN can take sometimes a minute to finally process to your server, where as the new api it's pretty much handled by you instantly. Here is a good tutorial on the new api https://youtu.be/BD1dOWIABe0 -
Well of course it's not going to have different values for each link, you're using the same var for each link. <td><a href="index.php?do=test2&sort=id&order='.$reverse.'">ID<img src="'.$arrow.'"></a></td> <td><a href="index.php?do=test2&sort=country_code&order='.$reverse.'">Country Code<img src="'.$arrow.'"></a></td> <td><a href="index.php?do=test2&sort=country_name&order='.$reverse.'">Country Name<img src="'.$arrow.'"></a></td> It's a little confusing as to what you are trying to do but I think it should be like this. //First link maybe should be $order or $sort <td><a href="index.php?do=test2&sort=id&order='.$order.'">ID<img src="'.$arrow.'"></a></td> <td><a href="index.php?do=test2&sort=country_code&order='.$reverse.'">Country Code<img src="'.$arrow.'"></a></td> <td><a href="index.php?do=test2&sort=country_name&order='.$reverse.'">Country Name<img src="'.$arrow.'"></a></td>
-
It was hard for me to read the code from my phone earlier. You weren't missing the closing ) on reverse, it was in the wrong place, you had it at the end of the line. Also, in order to use a ternary with an elseif ternary, the elseif must be enclosed in it's own set of (). $reverse = ($order == 'DESC') ? 'ASC' : 'DESC'; $arrow = ($sort == $get['sort'] && $order == 'ASC') ? 'files/images/table/sort_asc.png' : (($sort == $get['sort'] && $order == 'DESC') ? 'files/images/table/sort_desc.png' : 'files/images/table/sort_both.png');
-
You're missing a closing ) for the reverse var. you can't use 'and' in a if() expression, change that to && for $arrow
-
There isn't a [ in any of the array values, so that isn't going to work. The only common thing between all the array items is the word Exchange. Not much else you could consistently explode by in that array. The [ and ] symbols are the array keys, not the array items.
-
Yep, indexing those fixed it. Thanks!
-
Cool, that makes sense now. Any insight into my other recent posts?
-
One more thing. Why does SQL_CALC_FOUND_ROWS add 3 queries to the overall query run? I know that in order to get the number of rows from the SQL_CALC_FOUND_ROWS it runs an additional query, so I would think it only adds 1 to the overall query run, but it's adding 3. I know this cause I am running a page query test to see how many queries are being ran or a certain page and trying to reduce that to gain load speed. If I take out the SQL_CALC_FOUND_ROWS the query number is 7, with it in it's 10 and that is the only thing from the query string that I removed, which automatically tells my DB class not to run the additional query to get the total number of rows. For reference this is the part in the DB class that runs the additional query. if(strpos($this->_sql, 'SQL_CALC_FOUND_ROWS') !== FALSE) { $this->_found_rows = $this->_pdo->query('SELECT FOUND_ROWS();')->fetch(PDO::FETCH_COLUMN); } else{ $this->_found_rows = ''; }
-
Can you tell me why this query is soooo much slower. I mean like seconds slower too. SELECT SQL_CALC_FOUND_ROWS `".QUOTE_REQUESTS."`.*, qr1.id as already_quoted, `".QUOTE_RESPONSES."`.`id` AS `response_id`, `".QUOTE_RESPONSES."`.`read_quote`, `".QUOTE_RESPONSES."`.`quote_active`, `".QUOTE_RESPONSES."`.`viewed_by_txt`, `".QUOTE_RESPONSES."`.`viewed_by_email`, `".QUOTE_DEPOSITS."`.`id` AS `deposit_id` FROM `".QUOTE_REQUESTS."` LEFT JOIN `".QUOTE_RESPONSES."` qr1 ON qr1.`name` = `".QUOTE_REQUESTS."`.`name` AND qr1.`vehicle` = `".QUOTE_REQUESTS."`.`vehicle` LEFT JOIN `".QUOTE_RESPONSES."` ON `".QUOTE_RESPONSES."`.`request_id` = `".QUOTE_REQUESTS."`.`id` LEFT JOIN `".QUOTE_DEPOSITS."` ON `".QUOTE_DEPOSITS."`.`q_id` = `".QUOTE_RESPONSES."`.`id` GROUP BY `".QUOTE_REQUESTS."`.`id` ORDER BY `".QUOTE_REQUESTS."`.`id` DESC Than this original query SELECT SQL_CALC_FOUND_ROWS `".QUOTE_REQUESTS."`.*, (SELECT COUNT(`".QUOTE_RESPONSES."`.`id`) FROM `".QUOTE_RESPONSES."` WHERE `".QUOTE_RESPONSES."`.`name` = `".QUOTE_REQUESTS."`.`name` AND `".QUOTE_RESPONSES."`.`vehicle` = `".QUOTE_REQUESTS."`.`vehicle`) AS `already_quoted`, `".QUOTE_RESPONSES."`.`id` AS `response_id`, `".QUOTE_RESPONSES."`.`read_quote`, `".QUOTE_RESPONSES."`.`quote_active`, `".QUOTE_RESPONSES."`.`viewed_by_txt`, `".QUOTE_RESPONSES."`.`viewed_by_email`, `".QUOTE_DEPOSITS."`.`id` AS `deposit_id` FROM `".QUOTE_REQUESTS."` LEFT JOIN `".QUOTE_RESPONSES."` ON `".QUOTE_RESPONSES."`.`request_id` = `".QUOTE_REQUESTS."`.`id` LEFT JOIN `".QUOTE_DEPOSITS."` ON `".QUOTE_DEPOSITS."`.`q_id` = `".QUOTE_RESPONSES."`.`id` ORDER BY `".QUOTE_REQUESTS."`.`id` DESC
-
Thanks Barand, that worked great! I've never done stuff with alias tables, still trying to understand how they actually work. I understand what the <> '' is doing but I don't know the wording to describe it correctly. Like <= '' would be greater than or equal to nothing. But without the = sign in there I don't get how to describe it. Could you also help me understand this question from earlier?
-
Now I need help with another query I am trying to simplify. This one I have tried many ways and can't figure out. This is the version that works. SELECT (SELECT `name` FROM `quote_responses` WHERE `quote_responses`.`id` = `referrals`.`quote_id` AND `quote_responses`.`purchased` = FALSE) AS `name`, (SELECT `name` FROM `quote_responses` WHERE `quote_responses`.`id` = `referrals`.`ref_code`) AS `referral_name`, `referrals`.`id` FROM `referrals` WHERE `referrals`.`sent` = FALSE HAVING `name` != '' AND `referral_name` !='' ORDER BY `referral_name` ASC This is the modified version that does not work SELECT `referrals`.`id`, CASE WHEN `quote_responses`.`id` = `referrals`.`quote_id` AND `quote_responses`.`purchased` = FALSE THEN `quote_responses`.`name` END AS `name`, CASE WHEN `quote_responses`.`id` = `referrals`.`ref_code` THEN `quote_responses`.`name` END AS `referral_name` FROM `referrals` INNER JOIN `quote_responses` ON `quote_responses`.`id` = `referrals`.`quote_id` OR `quote_responses`.`id` = `referrals`.`ref_code` WHERE `referrals`.`sent` = FALSE HAVING `name` != '' AND `referral_name` !='' ORDER BY `referral_name` ASC The part that doesn't get data is the 2nd CASE. If I remove the AND `referral_name` !='' from the WHERE clause I at can see that it's pulling the name for the 1st CASE fine, just nothing for the 2nd. I've tried GROUP BY and rearranging the order of things, different JOINs, but nothing has worked. Please don't bother asking if the data is there or if it really references properly between the tables cause the first query has worked perfect from day one, I'm just trying to make things cleaner and faster.
-
Ok well I figured this out once I looked at a previous post I had made about a similar thing. The only part I couldn't figure out was how to get the total number of ratings in the query itself, so I just used a single line of code afterwards to sum it up. Here is the revised query string. SELECT `".PROD_REVIEWS."`.*, SUM(CASE WHEN `".PROD_REVIEWS_HELP."`.`helpful` = 1 THEN 1 ELSE 0 END) AS `helpful_yes`, SUM(CASE WHEN `".PROD_REVIEWS_HELP."`.`helpful` = 0 THEN 1 ELSE 0 END) AS `helpful_no` FROM `".PROD_REVIEWS."` LEFT JOIN `".PROD_REVIEWS_HELP."` ON `".PROD_REVIEWS_HELP."`.`prod_review_id` = `".PROD_REVIEWS."`.`id` WHERE $where GROUP BY `".PROD_REVIEWS."`.`id` ORDER BY `id` DESC
-
I have this query that gathers info from 2 tables but has 3 different where clauses. I am still learning some of the more advanced aspects of mysql, so I don't really know if/how I could simplify this query string to make it more efficient. The other thing I don't know is if simplifying it would reduce the actual number of queries ran within itself. One thing I also don't know is if there are multiple SELECT in a query string, does the query count increase for each of those SELECTS or is it still considered a single query overall. SELECT `product_reviews`.*, (SELECT SUM(`rating`) FROM `product_reviews` WHERE `active`= '1' AND `prod_id`='75') AS `total`, (SELECT COUNT(`prod_reviews_helpful`.`help_id`) FROM `prod_reviews_helpful` WHERE `prod_reviews_helpful`.`prod_review_id` = `product_reviews`.`id` AND `prod_reviews_helpful`.`helpful` = '1') AS `total_helpful_yes`, (SELECT COUNT(`prod_reviews_helpful`.`help_id`) FROM `prod_reviews_helpful` WHERE `prod_reviews_helpful`.`prod_review_id` = `product_reviews`.`id` AND `prod_reviews_helpful`.`helpful` = '0') AS `total_helpful_no` FROM `product_reviews` WHERE `active`=TRUE AND `prod_id`='75' ORDER BY `id` DESC Your insight is greatly appreciated!
-
As long as the jquery is on the index.php page then this method will work. $.ajax({ type: 'POST', url: 'content.php', data: { page: '<?php echo htmlentities($_GET['page']); ?>' }, success: function(data) {} }); Also, as long as this is purely for testing and learning, this whole concept is fine. But overall, your use of ajax in this scenario is completely pointless and makes the page even less secure. There is no reason at all to load content via ajax when you're simply telling it get that info on pageload only. The use of the ajax is to get different info AFTER the page is loaded and some kind of event has happened like a button click. Your content.php is not secured in any manner either, but I think I touched on that earlier.
-
include('config.php'); $sql = "SELECT * FROM `".$_POST['page']."`"; $mysql = mysql_query($sql); // This was wrong, you tried to run query on $select, which doesn't exist. while($row = mysql_fetch_array($mysql)) { $id = $row['id']; echo $id; } As for how to make the ajax change, well that's another issue. There are good ways to do it, but I need more of your jquery code that tells the page to run the ajax, so the click event and stuff.
-
There was still a lot to be desired with that script. Here is a reworked version. I didn't run the script to check to syntax errors, but the logic should be pretty close. I added lots of comments too. if(isset($_POST['submit'], $_POST['username'], $_POST['password'])) { $username = htmlentities($_POST['username']); $password = $_POST['password']; // Don't use the htmlentities on this unless you did so on the register side also, or they won't match. It's being hashed anyway, so not really needing to use htmlentities on it. $sql = "SELECT * FROM login WHERE username=?"; // ? Placeholder, you did it below, but not here for some reason. $get = $connect->prepare($sql); // Use prepare to prevent SQL injection $get->execute(array($username)); // Execute the query if($get->rowCount() === 1) { $row = $get->fetch(PDO::FETCH_ASSOC); // Fetch the result $db_username = $row['username']; $db_password = $row['password']; if(password_verify($password, $db_password)) { $_SESSION['username'] = $db_username; // Don't use the POST version just to be safe, use the DB record version. $sql = "UPDATE login SET last_login=?, ip=? WHERE id=?"; $statement = $connect->prepare($sql); $statement->execute(array($dt,$ip,$row['id'])); // easier to simply put $row['id'] in here rather than assign a var to $id for a single use of the var $id. //reloadPage(); // This function either needs to NOT be a function and simply echo out the info, or put in a separate file with other functions. Plus you didn't actually call the function, you only created it, so the info wouldn't have shown anyway. function loginstats() { global $last_login,$dbip; echo "Welcome back: "; echo $_SESSION['username']; echo "<br />Last Login:"; echo $last_login; } loginstats(); } else { echo 'Wrong Username / Password'; } } else { echo 'Wrong Username / Password'; } } else { echo 'Not all credentials were provided. Please try again.'; }