0

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.

Kevin Kopf
  • 13,327
  • 14
  • 49
  • 66
Abraha
  • 9
  • 4
  • So what's the issue? What is actually happening? Any errors showing? Any messages in your log file? – Jonnix Mar 03 '18 at 23:11
  • 3
    Sounds like you are molesting an OOP corpse here... – Kevin Kopf Mar 03 '18 at 23:12
  • 1
    http://sandbox.onlinephpfunctions.com/code/e8f3b0ef5fdf6f6c744310ad7bc31fd74a83e778 works for me – apokryfos Mar 03 '18 at 23:29
  • You should show us the `User` class first. –  Mar 03 '18 at 23:33
  • 1
    Is that code snippet all in the same file and scope? In other words, `//location2` is not in a different function or class than `//location1`. If it is in a different function or class, that could be causing the problem you are experiencing. – Cave Johnson Mar 03 '18 at 23:36
  • @Jon Stirling: what is happening is that the echo is empty, I used echo just as an abstraction for what I really want to print, but echo shows really nothing, too – Abraha Mar 04 '18 at 00:22
  • @Kodos Johnson yes it should be the same scope, yet in the "IF" brackets it works, and when I try to print it elsewhere it doesnt – Abraha Mar 04 '18 at 00:25
  • Are you showing all of your code? If not, can you reduce the code and reproduce it? My hunch is that you have an error in your code between location1 and location2 and that error is preventing location2 from executing and your server is configured to not show errors. Try adding `ini_set('display_errors', '1');error_reporting(E_ALL);` to the top of your php. – Cave Johnson Mar 04 '18 at 00:43
  • Can you show what you mean when you said you tried to use a global array? – Cave Johnson Mar 04 '18 at 00:46
  • Here is the User class http://sandbox.onlinephpfunctions.com/code/c032a6bd6a4f2cf153a2518f194ca035ee439a99 – Abraha Mar 04 '18 at 00:48
  • when using a global array: https://screenshots.firefox.com/rLZRXGF0lhKGOf3X/localhost When using the User instance: https://screenshots.firefox.com/JQ89gtbtUohhfriQ/localhost – Abraha Mar 04 '18 at 00:56
  • @Kodos Johnson: I used that "local scope" $user, which is containing the User instance at this point, and copied its data to the $_SESSION array: $_SESSION['user'] = array($user->__get('username'), $user->__get('email')); This only works at //location1 – Abraha Mar 04 '18 at 01:01
  • The full code is here (note that this is the working one, with an array) : https://github.com/Abrahalhabachi/Pikala concerned files are: index.php - /model/user.class.php - /core/login_function.php - /views/pages/user.php (is the page that tries to display the array) – Abraha Mar 04 '18 at 01:12
  • In the snippet you shared, you are using `$GLOBALS`, but in github repo, you are using `$_SESSION`. `$GLOBALS` only exist for the lifetime of the request. Meaning that it doesn't actually save anything to the session. When they submit the form, they won't stay logged in. You need to use `$_SESSION` for that, which you have done in the code in your repo. – Cave Johnson Mar 04 '18 at 01:23
  • @Kodos Johnson Oh thank you, that explains it, I thought they were equivalent since they are both super global and took one randomly, which happened to be the correct one. I am gonna try and store my User instance in $_SESSION and see if it works. – Abraha Mar 04 '18 at 01:28
  • Just for the record, there is NEVER, and I literally mean NEVER a reason to use the `global` or `$GLOBALS` supervariable in PHP. Not only is it a terrible practice, you can obtain the same global like functionality by use of static members in classes. Any developer that advocates the use of globals in php should be not allowed near a computer. – Geoffrey Mar 04 '18 at 06:12
  • @Geoffrey, what hogwash, a static member is just another global. – Progrock Mar 04 '18 at 09:57
  • @Progrock I did not state it wasn't another global, I was stating that the use of the `globals` and `$GLOBALS` super variable is extremely poor form unless you like your code to clash with other code that happen to chose the same global name as you have, or you like very convoluted code that is hard to maintain. See: https://stackoverflow.com/questions/8715897/why-is-it-considered-bad-practice-to-use-global-reference-inside-functions – Geoffrey Mar 05 '18 at 02:40
  • @Geoffrey "Any developer that advocates the use of globals in php should be not allowed near a computer.", perhaps hyperbole, but might be read as an absolute. You contradict that statement in your previous sentence. Surely better to suggest the avoidance of global variables as they are considered bad practice (with an accompanying reference). Link above is poor quality. – Progrock Mar 05 '18 at 09:37

2 Answers2

0

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>
Progrock
  • 7,373
  • 1
  • 19
  • 25
  • Tried to pass it as an argument, per value and per reference, neither worked. What I am trying to do is: the user logs in when he clicks on "account" he sees his info so the info gotta be somewhere: in a user instance, or an array. when displaying the info from an array, it works fine when displaying the info from an instance, it shows nothing, it hangs at the 1st variable to show (doesnt even show the static html code after that) – Abraha Mar 04 '18 at 00:28
0

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.

Abraha
  • 9
  • 4