I can't fetch an array inside a function but I can do it outside of the function. When I fetched it outside the function and echo it out, it prints out 1, but inside the function, using the same fetch array codes and echoing it out, it echos as null. I can tell because the --- symbols echos out, but the number 1 doesn't. I'm confused, because if it worked outside the function, the same code should work inside a function, right? Unless I'm doing something wrong? Please help. Thanks.
<?php
include('connect.php');
include('username.php');
//include('functionGet.php');
$boo = $_GET['boo'];
echo "$boo";
function getData($select,$from,$where,$equals){
$fetch = mysql_fetch_array(mysql_query("SELECT acceptedChallenges FROM
userLogin WHERE username = '$username'"));
$fetch = $fetch['acceptedChallenges'];
echo "---$fetch---";
}
if($boo = 'yes'){
$acceptedChallenges =
getData("acceptedChallenges","userLogin","username",$username);
$fetch = mysql_fetch_array(mysql_query("SELECT acceptedChallenges FROM
userLogin WHERE username = '$username'"));
$fetch = $fetch['acceptedChallenges'];
echo "$acceptedChallenges$username$fetch";
//mysql_query("UPDATE userLogin SET openChallenges = '0' WHERE username =
'$username'");
//mysql_query("UPDATE userLogin SET acceptedChallenges =
'$acceptedChallenges' WHERE username = '$username'");
}
else{
}
?>
you are passing $where instead of $username so change
function getData($select,$from,$where,$equals){
to
function getData($select,$from,$username,$equals){
You're using $username in your query, but there's no such variable in your function:
function getData($select,$from,$where,$equals){
$fetch = mysql_fetch_array(mysql_query("SELECT acceptedChallenges FROM
userLogin WHERE username = '$username'"));
$fetch = $fetch['acceptedChallenges'];
echo "---$fetch---";
}
In regards to the discussion in comments, here's a clip to demonstrate variable scope:
$username = "Testing";
function test1() {
echo $username; // Will emit Notice, since $username is undefined
}
function test2() {
global $username;
echo $username; // Will work, but this is bad practice
}
function test3($username) {
echo $username; // This is the proper way to do it
}
test1();
test2();
test3($username);
You can play with it here.
This code souns very bad:
Dont eval string with the variable if ouy have the variable echo $boo;
Don't use eval string ", use non eval ' and concat variables
Put globales off and escape the variables before query to prevent injection mysql_real_escape
Do a class to abstract data, not a function
Use non deprecated connect db functions like mysqli or pdo
Don't use static funcions to connect, use an instance of the library and his methods, is clear and more simple $db=new Mysqli()
Don't concat 2 or 3 functions, set the result in a variable and continue in a next line.
Iterate the result of fetch with if or while depending you have one or more results, don't get the result directly
Don't close php tag if you only have php
I suggest:
Set globales off if you have on in your php (show if on with phpinfo()
Create a instance of database using PDO library $db=new PDO()...
Create a class to get database information for everhy entity for example ChallengeObject with a method to get information function get($user)
Instance the ChallengeObject and pass to the constructor the database connection instance.
Inside get() function use prepared statements to pass data and prevent injection
private databse;
function __construct($database) {
$this->databse=$databse;
}
function get($user) {
$sql='SELECT acceptedChallenges FROM userLogin WHERE username = :user';
$this->database->prepare($sql)
$this->database->bindParam(":user",$user,'PDO::INT_VALUE);
$this->database->execute();
if ($user=$this->databse->fetch()) {
return $user;
}
return false;
}
<?php
$database=new PDO(...);
$challengeObject=new ChallengeObject($database);
$user=$challengeObject->get($_POST['boo']);
if ($user!=false) {
echo "Authenticated successfull";
}
Related
Good Day Everyone, Sorry if i made a lot of mistakes in my code but i am new to object oriented programming in PHP as i heard it is easily readable and organizes code.
I am trying a first project by working on a Login Script with mysql database.
The issue is i have written my functions but can seem to get it to work and i am not getting any errors to use to debug. Below are my codes.
I have a database.php file that contains most functions
class Database
{
//Database conn properties
private $host = 'localhost';
private $user = 'root';
private $pass = 'password';
private $dbname = 'rtmdb';
private $dbh;
private $error;
private $stmt;
public function __construct()
{
//Function for database connection
//Set DSN
$dsn = 'mysql:host='. $this->host . ';dbname'. $this->dbname;
//Set Options include persistent connection
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
//Create new PDO Instance
try
{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
}
catch(PDOException $e)
{
$this->error = $e->getMessage();
}
}
public function query($query)
{
//#param function for executing insert, select, update
$this->stmt = $this->dbh->prepare($query);
if(!$this->stmt)
{
echo $this->dbh->lastErrorMsg();
}
else
{
return $this->stmt = $this->dbh->prepare($query);
}
}
public function bind($param, $value, $type = null)
{
if(is_null($type))
{
switch(true)
{
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default;
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}
public function clean_str($data)
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
$data = str_replace("'", "’", $data);
return $data;
}
public function execute()
{
return $this->stmt->execute();
}
public function lastInsertId()
{
$this->dbh->lastInsertId();
}
public function resultset()
{
$this->execute();
return $this->stmt->fetchAll(PDO::FETCH_ASSCO);
}
public function registerAdmin($fname, $lname, $oname, $uname, $email, $idnumber, $pass, $profimg, $status)
{
$email = $this->clean_str($email);
$lname = $this->clean_str($lname);
$email = $this->clean_str($oname);
$lname = $this->clean_str($uname);
$email = $this->clean_str($email);
$lname = $this->clean_str($idnumber);
$email = $this->clean_str($pass);
$lname = $this->clean_str($profimg);
$email = $this->clean_str($status);
$database->query('INSERT INTO admin (fname, lname, oname, uname, email, idnumber, pass, profimg, status) VALUES(:fname, :lname, :oname, :uname, :email, :idnumber, :pass, :proofimg, :status)');
$database->bind(':fname', $fname);
$database->bind(':lname', $lname);
$database->bind(':oname', $oname);
$database->bind(':uname', $uname);
$database->bind(':email', $email);
$database->bind(':idnumber', $idnumber);
$database->bind(':pass', $pass);
$database->bind(':profimg', $profimg);
$database->bind(':status', $status);
$database->execute();
if(!$database->lastInsertId())
{
die('Yawa Don Gas: ' . $this->dbh->lastErrorMsg());
}
$this->dbh->close();
}
public function loginAdmin($uname, $pass)
{
$uname = $this->clean_str($uame);
$pass = $this->clean_str($pass);
$database->query('SELECT * FROM admin WHERE uname = :uname AND pass = :pass');
$database->bind(':uname', $uname);
$database->bind(':pass', $pass);
$results = $database->execute();
$count = mysql_num_rows($results);
if ($count == 1)
{
$rows = $database->resultset();
foreach($rows as $row)
{
$id = $row['id'];
$uname = $row['uname'];
$pass = $row['pass'];
}
if(!isset($uname) or empty($uname))
{
echo 'Invalid Usernmae';
}
elseif(!isset($pass) or empty($pass))
{
echo 'Invalid Password Details';
}
else
{
echo 'Good';
$set = $this->crossEncryption(ENCRYPT_KEY, 10).$id;
setcookie('itravel', $set, time()+COOKIE_EXPIRE, COOKIE_PATH);
}
return;
$this->dbh->close();
}
}
public function crossEncryption($key,$length)
{
$characters = $key;
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
return $randomString;
}
public function logout()
{
if(isset($_SESSION['uname']))
{
unset($_SESSION['uname']['id']);
session_destroy();
header('Location: index.php');
}
}
}
I have another travelapis.php file
<?php
require_once 'database.php';
class travelapis
{
public function __construct()
{
$this->dbh = new Database;
}
public function login()
{
if(isset($_POST['uname']))
{
$uname = $_POST['username'];
$pass = $_POST['password'];
if(empty($uname) || empty($pass))
{
echo 'Please Fill in all Fields';
}
else
{
$this->dbh->login($uname, $pass);
}
}
}
}
Then also a login.php file to carry out the function
<?php
require_once "travelapis.php";
$api = new travelapis;
$api->login();
This is used in the form action. For some reason i really don't understand, this doesn't seem to work. Any help would to as i need to wrap my head around OOP with PHP
The main issues I can spot, in no particular order:
You don't really have an object oriented design. You have a single Database class that does everything. It's mostly procedural code where Database plays the role of index.php. I'd expect classes for each different concept involved: database connection, database result, administrator... And maybe some design pattern that helps with application flow (such as Model-View-Controller). What will you do when you need to implement e.g. a contact form? Add new methods to your megaclass?
You're actively preventing proper error handling: try/catch on connection to hide the exception, die() in the middle of nowhere
Methods are unpredictable: they return stuff or print to stdout (often both) without a hint.
You have hard-coded global variables popping up from nowhere in some methods (e.g. login().
clean_str() has no reason to exist. If you want to keep it, give it a better name like randomlyCorruptInputData().
The database features of the class do not really have any advantage over using raw PDO. It actually makes it harder because you need to learn a new API and some PDO features become unavailable.
In spite of all my comments below, it looks like you are learning OO. Keep working on it. I'm not necessarily going to find your bug for you, but rather push you forward. After you have revised some of your code to handle the stuff below, the bug may vanish.
Something to think about in designing OO code:
It should not be a thin layer. (Else, why bother?)
It should isolate the implementation end from the business-end.
The user of the OO package should not necessarily need to understand the underlying processes.
Related to that last item:
Consider doing travelapis::login from within travelapis::__construct.
The caller should not have to understand prepare-bind-execute-inserted_id -- See if you can roll those together into a single call.
Ultimately, the business-end should not even know what "tables" exist, much less how many exist. It should say "put/get" these things into/from the database. The package would then take care of JOINing tables, iterating, etc; thereby hiding the schema from the business-end.
A select script should simply return an array of results. Perhaps 2 versions -- an array of arrays versus an array of hashes (associative arrays).
Now for some nit-picks / bugs...
Don't prepare twice.
Don't stripslashes; they will already be gone (unless you erroneously doubled up on addslashes).
Don't htmlspecialcharacters except when immediately putting in HTML.
Consider extending PDO instead of having to always say $this->dbh->
Consider adding something. Why mimic inserted_id when you could have that returned from the query execution (for example).
Don't bother with mysql_num_rows if you can just as easily do count($rows)
Bug with lots of $lname= and $email=
clean_str is probably totally useless. Maybe trim is useful; bind does what mysql needs; the rest is "wrong".
There is some code after a return;??
empty checks for isset.
First off, all of the previous answers have really valid and constructive comments.
I am going to assume that you are fairly new to php and OOP. That being said this is not something that you are just going to spend a night coding and be done with.
However, you still need to write a login script from start to finish. Then you need to evaluate your project and determine where you had problems or struggled trying to get something accomplished. Then you need to come up with a way to do it better,which is usually just a result of more simplified and structured logic.
Let's look at this from a login system point of view. What do you have to do to log someone in. Let's look at what it is you are truly dealing with.
Keeping it simple you will be dealing with:
Users
Passwords
Validations
Formatting
Errors
Hint - Each one of these will end up being a class that handles those things. Not only will the classes deal with those things, but they will deal exclusively with those categories and will be called whenever you need to do any of the above things.
I will show you a very simple example. When you make your login form you are going to most likely have two inputs, a username and a password. You are going to want to validate those inputs for a few things. Like, for example, are the username and passwords blank, or long enough.
So you would make a validation class that contains functions that will check and validate those conditions. Like so:
class Validate{
public function __construct(){
}
//Just testing to see if it is empty. You can add any other criteria to this that you want.
public function userName($userName){
if(isset($userName) && $uerName){
return TRUE;
}else{
return FALSE;
}
}
//Just testing to see if it is empty. You can add any other criteria to this that you want.
public function password($password){
if(isset($password) && $password){
return TRUE;
}else{
return FALSE;
}
}
}
Now to use this just call the class Validate and pass your username and password to check if they are valid.
$valid = new Validate();
if(!$valid->userName($_POST['username'])){
echo 'Sorry, There is something wrong with your username.';
}
if(!$valid->password($_POST['password'])){
echo 'Sorry, There is something wrong with your password.';
}
Here are where classes are really cool. Eventually you are going to want to validate many different things, emails, phone numbers, names, addresses, ect.. Just add a new function to your Validate class and anytime you want to validate you just call your class and the function you require, like valid->email()
Even better yet, you know exactly where your code is so when you realize you need to change how something gets validated you make your edits in the class in one function and it works across your entire code base.
Like I said before, you will make an individual class for all those categories. I think after tinkering around you will see how this is huge plus.
Another thing is not to get discouraged. It's called learning.. You will make mistakes and you will earn from those mistakes. The important thing is to just keep coding.
Hope this helps you. Good luck!
PHP student here Consider the following 2 methods the 1 method checks if a user exists the other registers a user.
public function is_registered($userEmail)
{
$this->email = $userEmail;
$sql = "SELECT * from users WHERE email = :email";
$stmnt = $db->prepare($sql);
$stmnt->bindValue(':email', $userEmail);
$check = $stmnt->execute();
if($check >= 1) {
return true;
}
else {
return false;
}
}
public function register_user($email, $pword, $firstname, $lastname)
{
$this->email = $email;
//call method is_registered inside register user class
$registered = $this->is_registered($email);
if($registered == true){
die("USER EXISTS");
}
else {
//continue registration
}
}
Although this might not be the best use case example I basically want to know:
Is "normal / good practice" to call a method inside a method. Another use case might be calling a get_email() method inside a login() method or similar method where you need an email address.
What is the difference if I set a property inside a method or just access the passed parameter directly? Example:
Method with set property
public function is_registered($userEmail)
{
$this->email = userEmail // SET PROPERTY
$sql = "SELECT * from users WHERE email = :email";
$stmnt = $db->prepare($sql);
$stmnt->bindValue(':email', $userEmail);
}
Method with no set property.
public function is_registered($userEmail)
{
//NO SET PROPERTY
$sql = "SELECT * from users WHERE email = :email";
$stmnt = $db->prepare($sql);
$stmnt->bindValue(':email', $userEmail);
}
Hope this makes sense, any help or guidance much appreciated.
On the point of view of OOP, both approaches are kinda weird. Since your User class doesn't seem to be static, and since the e-mail address is one of the major uniqueness discriminant for authentication, your class should be instantiated with a valorized email property that never changes... either upon database extraction (1) or form filling (2):
$user = new User(..., $auth->email); (1)
$user = new User(..., $_POST['registration_mail']); (2)
On the top of that, a method named is_registered should really not mess with assignments. All it should do is to check whether the current User instance class is defined in your database or not.
In your first approach, the risk is to mess up everything. Let's suppose you have the following user:
$user = new User('John', 'john#domain.com');
Now, let's see what happens when, by mistake, you pass the wrong email as argument:
$result = $user->is_registered('marley#domain.com');
echo $user->name; // John
echo $user->email // marley#domain.com
In your second approach, you should not allow the is_registered to accept any argument since, as I explained you before, that property should be defined upon creation to avoid fatal mistakes. Let's bring back the same user we used in the first example:
$user = new User('John', 'john#domain.com');
Now, let's see what happens when, by mistake, you pass the wrong email as argument (john#domain.com is registered, marley#domain.com isn't):
$result = $user->is_registered('marley#domain.com'); // false
So my suggestion is, initialize the property upon the creation of the instance and never mess with it. Alternatively, you could implement a static function into a utility class that, for a given email, performs the desired check. But try to make your OOP design as strict as possible.
I am relatively new to OO PHP and I am trying to create a login class.
The issue I am having is that I want to pass the POST values username and password to my class but I cannot establish a decent way of doing so.
below is a snippet of my class
class PortalLogin{
private $username;
private $password;
function __construct(){
//I connect to DB here
}
function login($username, $password){
//error check the paramaters here
//then I can run the query
}
function __destruct(){
//I disconnect from DB here
}
}
Above is a breakdown of the class I am creating below is how i plan to execute it (my main issue at the moment).
$login = new PortalLogin();
if(isset($_POST['username'])){
if(isset($_POST['password'])){
$login->login($_POST[username],$_POST[password]);
} else {
//throw error
}
} else {
//throw error
}
I really do not like the construction of the code above it seems to messy to be doing so much outside of my class. how can I pass the POST information to the class and execute the checks there? I am worrying that if I pass the POST information to the class and one of the POSTS contains nothing it will error.
I think you got a problem with the syntax of post..
if(isset($_POST['username']) && isset($_POST['password'])){
$login->login($_POST['username'],$_POST['password']);
}
use AND.. so if both username and password exist then call the login function()
I’m not sure where OOP comes in to this, but if you were going the object-oriented route you would have a class that represents a request from which you could grab POST data from:
$username = $request->post('username');
$password = $request->post('password');
Your post() method could return a default value (null) if the variable didn’t exist in the POST data.
You could then have a class that checks your user based on these variables:
$auth = new AuthService($dbConnection);
if ($auth->checkCredentials($username, $password)) {
// Valid user
} else {
$error = $auth->getLastError();
}
I know I might be in the minority with suggesting this, but I favour static methods for things like this. PortalLogin represents an action rather than data
class PortalLogin
{
/**
* Attempt login
* #param string $username
* #param string $password
*/
public static function login ($username, $password)
{
// do your login stuff
}
}
Then to use you would do this:
if (isset($_POST['username']
&& !empty($_POST['username']
&& isset($_POST['password']
&& !empty($_POST['password']
) {
PortalLogin::login($_POST['username'], $_POST['password']);
}
Even better OO would be to have the username/password checking baked into the User class. (Maybe User::checkLoginCredentials($u, $p); // boolean yup/nope)
You can use error suppression, like this:
$login->login(#$_POST['username'], #$_POST['password']);
If one or both values are not present in the $_POST variable, there won't be an error when calling the method, so you can do the error handling inside your class method.
For more info, check:
http://php.net/manual/en/language.operators.errorcontrol.php
Edit:
Another option is to do this:
$login->login((isset($_POST['username']) ? $_POST['username'] : null), (isset($_POST['password']) ? $_POST['password'] : null));
<?php
if (isset($_GET['confirm_code'])) {
__construct();
}
function __construct() {
global $wpdb;
$table_one = $wpdb->prefix . "fantasticemailnewsletter_temp";
$confirm = $_GET['confirm_code'];
$mylink = $wpdb->get_results("SELECT * FROM $wpdb->$table_one WHERE confirm_code = $confirm");
if ($mylink) {
echo $mylink->confirm_code;
echo "success";
echo $wpdb->show_error();
} else {
echo "You Subscription is not process right now please try again later";
}
}
?>
I’m trying to create a newsletter plugin in WordPress. I make a confirmation link for the corresponding subscriber to prevent spammers, creating a random key for every subscription e-mail. I pass the random key with query string through mail like this:
http://www.example.com/wp-content/plugins/plugininname/includes/subscriber.php?confirm_code=%2248c9c7d48165379b49f58962c0092466%22
In subscriber.php only, I’m using the above code, but for some reason, there’s an error at get_results():
Fatal error: Call to a member function get_results() on a non-object
How can I overcome this prob.
The error looks like the object of wpdb hasn't been instantiated.
Generally a method of a class shall be called after an object has been instantiated, if the method is not a static one. Otherwise this error shows.
I would check other parts of code or the file to see whether it's executed before WP code.
For example, if the file isn't a plugin or a theme (which means the file stands alone) and you haven't properly called WP framework header file before executing this file, the $wpdb object may not have been instantiated. I would definitely try the code by #Rikesh in the comment of your question.
you dont need to redeclare wpdb in query $wpdb-> as you already declared in this line $table_one = $wpdb->prefix . "fantasticemailnewsletter_temp";
<?php
if(isset($_GET['confirm_code'])) {
__construct();
}
function __construct() {
global $wpdb;
$confirm = $_GET['confirm_code'];
$mylink = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}fantasticemailnewsletter_temp WHERE confirm_code = $confirm");
if($mylink) {
echo $mylink->confirm_code;
echo "success";
echo $wpdb->show_error();
}
else {
echo "You Subscription is not process right now please try again later";
}
}
?>
$query = $wpdb->query("SELECT * FROM $wpdb->$table_one WHERE confirm_code = $confirm");
$mylink = $wpdb->get_results($query);
I am currently writing a login script because I am trying to learn PDO using OOP. I have a index.php page which only contain a login form. Then I have a User class, it looks like this:
<?php
include_once('database.php');
session_start();
class User{
public $id;
public $username;
public $password;
public $firstname;
public $lastname;
public function Login($username, $password) {
$db = new Database;
$db = $db->dbConnect();
$query = "SELECT * FROM users WHERE username = ? AND password = ?";
$statement = $db->prepare($query);
$statement->bindParam(1, $username);
$statement->bindParam(2, $password);
$statement->execute();
$rows = $statement->rowCount();
$data = $statement->fetchAll();
if( $rows == 1 ) {
$this->id = $data[0]['id'];
$this->username = $data[0]['username'];
$this->password = $data[0]['password'];
$this->firstname = $data[0]['firstname'];
$this->lastname = $data[0]['lastname'];
$_SESSION['SESSID'] = uniqid('', true);
header("location: dashboard.php");
}
}
}
?>
When the user is signed-in he/she goes to dashboard.php. I want to access the current User class from there, so I can use echo $user->username from there. But in dashboard.php, I have to declare the User class as new, so it doesn't keep all the variables.
Do you have any ideas on how i can access the User class variables in Dashboard.php which was declared in the Login-function?
Sorry for the bad explanation, but I hope you understand. Thank you in advance!
First off put your user class definition in another file and load it in like you do your database.php. In there you want only your class definition none of the session start business... <?php class User {....} ?> (the closing ?> is optionial).
so what you have now on your pages that need access to the user object is
<?php
include_once('database.php');
include_once('user.php');
session_start();
Then after a user has successfully logged you tuck the user in the session.
$_SESSION["user"] = $user;
Then when you want to get at it just say
$user = $_SESSION["user"];
echo $user->username;
What you could do is, put your user object into the session:
$obj = new Object();
$_SESSION['obj'] = serialize($obj);
$obj = unserialize($_SESSION['obj']);
or you could create a singleton, check out this link:
Creating the Singleton design pattern in PHP5
You have 2 options:
a) You store all the login info in a session.
b) You only store the user ID and some sort of identifier that the user has / is logged in, and create another method that will load the information from the database each time you load the page (bad idea really)
For example, you could add the following methods to your class in order to implement the above mentioned functionality and some more:
function createUserSession(array $userData) {
// Create / save session data
}
function readActiveUserSession() {
// Read current user information
}
function destroyActiveUserSession() {
// Call to destroy user session and sign out
}
Of course, you will have to add the appropriate code to the methods.