PHP: Set a global variable from within a function - php

I have the following code
$user;
if (isset($_POST['submitLogin']))
{
$GLOBALS['user'] = logIn();
// location1
}
function logIn()
{
$user = new User("my username", "my email");
return $user;
}
// location2
Then I want to display that information like this:
echo $GLOBALS['user']->__get('username');
but it only works in location1.
I have worked around this by using a global array and passing the data from the User instance to that global array, but this defeats the purpose of using classes.
If you could just give me a hint or put me on the right track I'd be very thankful.

I don't quite follow what you are asking. But you can always pass objects to functions through arguments, rather than using globals. Demonstration here:
<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
class UserSignup
{
public $username;
public $email;
public function __construct($username, $email)
{
$this->username = $username;
$this->email = $email;
}
}
function process_signup_form()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$user = new UserSignup(
$_POST['username'] ?? null,
$_POST['email'] ?? null
);
if(signup($user))
echo 'Thanks for signing up!';
}
}
function signup(UserSignup $user)
{
echo 'Signing up:' . $user->username . ' with email:' . $user->email;
return true;
}
process_signup_form();
?>
<form method="post">
<input type="text" name="username">
<input type="email" name="email">
<input type="submit">
</form>

As stated here: https://stackoverflow.com/a/132197/9439763
it's OK [to store an object inside $_SESSION] as long as by the time the session_start() call is made, the class declaration/definition has already been encountered by PHP or can be found by an already-installed autoloader. otherwise it would not be able to deserialize the object from the session store.
This was the problem, I now fixed it by including the class declaration before the session call.
<?php
require_once './model/user.class.php';
session_start();
...
Thank you all, and a special thanks to #Kodos Johnson for showing me the way.

Related

PHP class, html forum, print $_POST Array on page

i am beginner php programmer, iv been trying to create a small program that takes input from a forum and then after submission i want it to be printed on the screen. simple and easy i thought, iv been trying and suspiciously it seems to work fine for 1 text field, when i added the remaining 2 text fields called [fam][user] my code stops returning the content to the screen. also i started to recieve an error of an unindex array, therefore i had to use isset to counter this problem, and also, why does my code call the destructor although i never implicitly set my destructor. i dont know how to ask these questions because the errors arent consistent.
code doesnt print my [name][fam][user]
code prints [name] when everything about [fam][user] are ommited from the code.
-code sometimes called the destructor
-code doesnt clear html previous input(e.g, when working with the one text field, lets say i input the [name] john, and click submit it
displays submit, then,i refresh the page, and the name john is still
displayed, why doesnt the destructor clear the memory of name from my
submission.
<form class="nameform" action="book.php" method="post">
<input type="text" name="Name" value="1">
<input type="text" name="Fam" value="2">
<input type="text" name="User" value="3">
<input type="button" name="submit" value="Submit">
</form>
private $name; private $familyName; private $userName;
function __construct($names,$familyNames,$userNames)
{
$this->name = $names;
$this->familyName = $familyNames;
$this->userName = $userNames;
}
function getName()
{
return $this->name;
}
function getFamilyName()
{
return $this->familyName;
}
function getUserName()
{
return $this->userName;
}
public function __destruct()
{
echo "destroyed again";
$this->name;
$this->familyName;
$this->userName;
}
}
if(!isset( $_POST["Name"])||!isset($_POST["Fam"])||!isset($_POST["User"]))
{
echo "Please fill in the data";
} else {
$p1 = new Person($_POST["Name"],$_POST["Fam"],$_POST["User"]);
print $p1->getName();
print $p1->getFamilyName();
print $p1->getUserName();
print_r($_POST);
}
// $n = $_POST["Name"];
// $f = $_POST["Fam"];
// $u = $_POST["User"];
// $p1 = new Person($_POST["Name"],$_POST["Fam"],$_POST["User"]);
?>
code doesnt print my [name][fam][user]
You never echo them out of the destuctor
public function __destruct()
{
echo "destroyed again";
$this->name; //<---- does nothing
$this->familyName;
$this->userName;
}
So I am not sure what this is supposed to do. You have them down at the bottom
print $p1->getName();
print $p1->getFamilyName();
print $p1->getUserName();
But the only thing you'll get from the destruct method is
"destroyed again"
And you will only see that if everything in the form is set. Which it always is when the form is submitted, because type text is always submitted with its form.
Which brings me to this, you should be checking empty instead of isset there
if ('POST' === $_SERVER['REQUEST_METHOD']) { //check if POST
if(empty($_POST["Name"])||empty($_POST["Fam"])||empty($_POST["User"])){
echo "Please fill in the data";
} else {
$p1 = new Person($_POST["Name"],$_POST["Fam"],$_POST["User"]);
print $p1->getName();
print $p1->getFamilyName();
print $p1->getUserName();
print_r($_POST);
}
}
Note that anything falsy will be empty, false, [], '', 0, '0', null etc.
I don't know if this solves all of you problems, but these things could produce some of the behaviour you are experiencing.
Another more advance way to check these is like this:
if ('POST' === $_SERVER['REQUEST_METHOD']) { //check if POST
$post = array_filter( $_POST, function($item){
return strlen($item); //any thing of a length of 0 is removed
});
if(count($post) != count($_POST)){
foreach(array_diff_key( $_POST, $post) as $missing=>$empty) {
echo "Please fill in $missing\n";
}
}else{
$p1 = new Person($_POST["Name"],$_POST["Fam"],$_POST["User"]);
print $p1->getName();
print $p1->getFamilyName();
print $p1->getUserName();
print_r($_POST);
}
}
Output
Please fill in Name
Please fill in Fam
You can test it online Here
Cheers!

Spanning PHP files but method wont echo variables

This is a college assignment, so I know you wouldn't do this because it would be too easy to hack. I have searched so hard on this website too and I'm at a dead end. So here it is I have multiple PHP files where I am trying to pull variables across and print out hard coded user information. But my last login in function throws an error no matter what i change i keep getting different errors.This has to be done primarily with PHP and avoiding using SESSION. Any help or direction is appreciated.
My index form is straight forward.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>sample</title>
</head>
<body>
<style>
</style>
<form action="method.php"; method="POST">
Name<input type="text" name="userName">
Password<input type="text" name="password">
<input type="submit" value="Login">
</form>
</body>
</html>
my method.php is straight forward too and works.
<?php # person
$name1= $_POST['userName'];
$password=$_POST['password'];
//echo 'testclass.php#' . $name;
include 'testclass.php';
?>
But my method credentials won't work in this, it won't find name1 or password?
<?php
class UserController {
//private $name1;
//private $password;
private $isLoggedIn = false;
// Credentials
public function credentials() {
$credentials = array(
array(
"username" => "Goat",
"password" => "1234"
),
array(
"username" => "Goat",
"password" => "1234"
)
);
return $credentials;
}
// Basic login
public function login() {
foreach ($this->credentials() as $credential) {
//not finding name 1 and password even though its been called in this php file.
if ($this->name1 == $credential['username'] && $this->password == $credential['password']) {
$this->isLoggedIn = true;
}
}
if ($isLoggedIn = true){
echo "YAYAYA";
}
else{
echo "sad";
}
}
}
$user = new UserController();
$user->credentials();
$user->login();
?>
Many thanks.
$this->name1 does not exist as a class property. You cannot access those variables like that inside your UserController. You need to pass your parameters over to the login function.
public function login($username, $password)
{
foreach ($this->credentials() as $credential)
{
if ($username == $credential['username'] && $password == $credential['password']) {
$this->isLoggedIn = true;
}
}
}
$user = new UserController();
$user->login($_POST['username'], $_POST['password']);

How to grab data from post to a class Object

I have been trying to write data from a form submit into a PHP class object. I'm using the following basic submit form.
<html>
<body>
<h2>Form Submit</h2>
<form action='object_of_array2.php' method='POST'/>
<input type="text" name='first_name' value=''/><br/>
<input type="text" name='last_name' value=''/><br/>
<input type="text" name='email_address' value=''/><br/>
<input type='Submit' name='submit' value='GO'/>
</form>
</html>
</body>
I found a previous article, How to grab data from post to a class. Which works with my submit form.
<?PHP
class RegisterUser {
private $firstName;
private $lastName;
private $emailAddress;
function __construct() {
$this->firstName = isset($_POST['first_name']) ? $_POST['first_name'] : null;
$this->lastName = isset($_POST['last_name']) ? $_POST['last_name'] : null;
$this->emailAddress = isset($_POST['email_address']) ? $_POST['email_address'] : null;
}
function start() {
if (empty($this->firstName) || empty($this->lastName) || empty($this->emailAddress)) {
echo "Empty Post not allowed";
}
else
{
// Do some stuiff
echo " Registration Done";
}
}
}
$register = new RegisterUser();
if(!empty($_POST))
{
$register->start();
}
?>
I'm trying to figure out how I could echo $firstname, $lastname & $emailaddress. How can I access these for use elsewhere?
This is a quick and dirty way of doing this, since you want to write the values to a database, as you stated in comments: "Thanks Fred, I was referring to using the variables to write to MySQL.".
Simply use the $this->propertyName and assign each of them to a variable.
else
{
// Do some stuiff
echo " Registration Done" . "<br>";
$var1 = $this->firstName;
$var2 = $this->lastName;
$var3 = $this->emailAddress;
echo $var1 . " " . $var2 . " " . $var3;
// write to database here using the assigned variables
}
Note:
Writing to a database would be an entirely different matter and would be out of the scope of the question.
Remember to use a prepared statement at the time of insertion in order to help prevent against an SQL injection.
https://en.wikipedia.org/wiki/Prepared_statement
Sidenote about the use of isset().
Using isset() is usually best when using radio buttons/checkboxes.
empty() is better when user input is involved.
Reference:
Why check both isset() and !empty()

Learning OOP in PHP. Is this the correct way to do this?

I've just started learning to do oop and I just wanted to put the most basic set of code together to make sure I'm understanding things correctly. I wanted to capture a form entry in the $_POST variable and pass it to an object to have it output something back to the browser. No SQL, no Security measures, just proof of understanding.
Here is the form:
<html>
<head>
<title>SignUp Form</title>
</head>
<body>
<?php
if(!empty($_POST['name'])) {
include_once "class.php";
} else {
?>
<form method="post" action="signup.php">
<label for="name">Enter name below:</label></br>
<input type="text" name="name" id="name"></br>
<input type="submit" value="Submit">
</form>
<?php
}
echo $name->processName($_POST['name']); ?>
</body>
</html>
And here is the class:
<?php
class Process {
public $entry;
function __construct($entry) {
$this->entry = $entry;
}
public function processName($entry) {
return "You entered " . $this->entry . ".";
}
}
$name = new Process($_POST['name']); ?>
This is working without error right now but it doesn't seem like I should have to enter the $_POST in the echo statement on the form page and in the object on the class page. Is this correct? Should I instead be collecting that in the $entry property. It's working, but I don't think the execution is correct. Thanks in advance!
Your right you don't need to enter the $_POST variable into that function, you could change it to this and it would work without entering the post:
public function processName() {
return "You entered " . $this->entry . ".";
}
Because right now processName function doesn't do anything with the class's public $entry variable, it just echoes out what you put in when you call the function.
What you likely want to do instead is:
Change public $entry; to protected $entry;
Then:
public function getEntry() {
return $this->entry;
}
Then in your html, after constructing the class, you can just put this to get the $entry variable:
echo $name->getEntry();
Coming from Symfony framework background. You could do something right this:
<?php
class Process
{
protected $post_var;
public function __construct($p)
{
$this->post_var = $p;
}
public function getData()
{
//checking if not post request
if(count($this->post_var) == 0) {
return false;
}
$result_arr = [];
//populating $result_arr with $_POST variables
foreach ($this->post_var as $key => $value) {
$result_arr[$key] = $value;
}
return $result_arr;
}
}
$process = new Process($_POST);
$data = $process->getdata();
if($data)
{
echo $data["name"];
}
?>
<form action="" method="post">
<input type="text" name="name"/>
<input type="submit" name="submit"/>
</form>

Database Table Won't Update with Mysqli

So I have a problem with updating a mysql table via mysqli in php.
The database connection and class:
<?php
class testDB extends mysqli {
private static $instance = null;
private $user = "tester";
private $pass = "tester01";
private $dbName = "testdb";
private $dbHost = "localhost";
public static function getInstance() {
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}
public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
public function __wakeup() {
trigger_error('Deserializing is not allowed.', E_USER_ERROR);
}
private function __construct() {
parent::__construct($this->dbHost, $this->user, $this->pass, $this->dbName);
if (mysqli_connect_error()) {
exit('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
parent::set_charset('utf-8');
}
public function verify_credentials ($username, $password){
$username = $this->real_escape_string($username);
$password = $this->real_escape_string($password);
$result = $this->query("SELECT 1 FROM users WHERE user_username = '" . $username . "' AND user_password = '" . $password . "'");
return $result->data_seek(0);
}
public function get_vitae() {
return $this->query("SELECT * FROM vitae");
public function update_vitae($text, $id) {
$text = $this->real_escape_string($text);
$this->query("UPDATE vitae SET vitae_text=".$text." WHERE vitae_id = ".$id);
}
}
?>
Here's the page code:
Above the header we check the login by making sure there is a session started; then import the database class and the rest is called upon resubmitting the form to this same page:
<?php
session_start();
if (!array_key_exists("username", $_SESSION)) {
header('Location: index.php');
exit;
}
require_once("includes/db.php");
$vitae_empty = false;
if ($_SERVER['REQUEST_METHOD'] == "POST") {
if ($_POST['text'] == "") {
$vitae_empty = true;
} else if ($_POST["text"]!="") {
testDB::getInstance()->update_vitae($_POST["text"], $_POST["id"]);
header('Location: manage.php' );
exit;
}
}
?>
In the body (the header and the rest of the html is imported via a 'require_once'):
<section>
<div class="grid_3 header_line"><h2>Update for CV</h2></div>
<div class="grid_3">
<?php
$result = testDB::getInstance()->get_vitae();
$vitae = mysqli_fetch_array($result);
?>
<form name="editvitae" action="editvitae.php" method="POST">
<textarea name="text" rows="50" cols="100"><?php echo $vitae['vitae_text'];?></textarea><br/>
<?php if ($vitae_empty) echo "Please enter some text.<br/>";?>
<input type="hidden" name="id" value="<?php echo $vitae["vitae_id"];?>" /> <br/>
<input type="submit" name="savevitae" value="Save Changes"/>
</form>
</div>
<div class="grid_3">
<p>‹ back to management consol</p>
</div>
</section>
After the 'body' tag:
<?php mysql_free_result($result);?>
As you can see this pulls the 'vitae' text from the database then loops it to the same page with changes to update the table. It also check's to see that the 'text' box is not empty.
This code works in another application; I'm not understanding why it won't work here. AND before you start warning me about injection and security I have stripped most of it out trying to find the problem with the update. It WILL go back in once I can figure that out.
I have tried stripping the text check; different variable names; dumping the post values into an array before updating the database; putting the post values into static variables; checking all my spellings etc...
I'm missing something and I feel like it's going to be simple.
Anytime an UPDATE is run through mysqli you need to run the $mysqli->commit(); method.
Your new update_vitae would be:
public function update_vitae($text, $id) {
$text = $this->real_escape_string($text);
$this->query("UPDATE vitae SET vitae_text=".$text." WHERE vitae_id = ".$id);
$this->commit;
}
mysqli also has an autocommit feature that can be toggled on or off:
$this->autocommit(true); //on
$this->autocommit(false); //off
So the answer was indeed simple. It was my escaping on the update string as Andrewsi suggested. Here's the update that fixed it:
public function update_vitae($text, $id) {
$text = $this->real_escape_string($text);
$this->query("UPDATE vitae SET vitae_text = '$text' WHERE vitae_id = ".$id);
}
Thanks for the help!
I've been designing websites for almost 10 years, but I'm just now getting into 'real' php coding instead of using prepared classes and dreamweaver's built in functions. Far to much to learn but it's fun in my limited spare time.
$result = $this->query("SELECT 1 FROM users WHERE user_username = '" . $username . "' AND user_password = '" . $password . "'");
Be careful with using logical ANDs for user authentication. It may be more wise to completely validate the username first before going after any kind of password. I say this in regard to the many examples of people inserting --; WHERE 1=1 -- and stuff like that (not specifically this statement, however). Sure, this may require two queries, but at least you only have to process one piece of information to determine if a visitor is valid. Another advantage might be saving processing because you won't have to deal with hashing/encrypting the user's password in your app or at the database (until the username has been verified).

Categories