php variable scope in oop - php

I wonder if anyone can help out here, I'm trying to understand how use an objects properties across multiple non class pages,but I can't seem to be able to get my head around everything i have tried so far.
For example a class called person;
class person {
static $name;
}
but i have a number of different regular pages that want to utilize $name across the board.
I have trying things like this;
pageone.php
include "person.php";
$names = new Person();
echo person::$name;
names::$name='bob';
pagetwo.php
include "person.php";
echo person::$name;
I can work with classes to the extent I'm OK as long as I am creating new instances every page, but how can make the properties of one object available to all, like a shared variable ?
Thanks

Every new instance of a PHP script "forgets" everything done in previous scripts. The usual way of establishing a "storage room" for data across page loads is sessions. A session is essentially a specific ID a user gets when visiting a page. That ID is stored in a cookie, or a GET variable that is appended to every URL. PHP keeps text files in a special directory that can contain session specific data. Every file is named using the session ID.
The PHP manual has a thorough introduction here.
pageone.php
session_start();
$_SESSION["name"] = "Bob",
pagetwo.php
session_start();
echo $_SESSION["name"]; // Bob
Now if you had an instantiated object, you could serialize it, store it in a session variable, and unserialize it back in the 2nd page. I don't think that can be done with static classes though. But this should be a good start.

You need to initialize the static variable inside the class declaration itself:
class Person {
public static $name = 'bob';
}
Or, you need some bootstrapping mechanism, where you inititalize the static variable:
bootstrap.php:
Person::$name = 'bob';
and then in the pages:
// assuming, you preloaded the bootstrap somewhere first
$person = new Person();
echo $person::$name;
edit
Ugh, what was I thinking... the above won't even work. You can't access a static member like that on an instance. Only through a method, like so:
class Person
{
public static $name;
public function getName()
{
return self::$name;
}
}
// assuming, you preloaded the bootstrap somewhere first
$person = new Person();
echo $person->getName();
/end edit
Or as Pekka pointed out, use sessions to keep state.
But more importanty: what is the goal you are trying to achieve? If you want to maintain state of a Person object between different requests, then Pekka's route is the way to go, or alternatively use another persistance storage mechanism, like a DB, File, etc...
Because I presume you don't mean to have every single Person instance named 'bob' do you? I presume you mean to maintain state of a single Person instance.
So, concluding, you probably don't want to use a static member to begin with.

Related

Php global variable range?

update:
the code i put below will be invoked by a form on other webpage. so that's why I didn't made a instance of a obj.
More detail code:
$serverloc='serverURL';
class Aclass{
function push(){
global $serverloc;
echo $serverloc;
funNotinClass();
}
function otherFunction(){
echo $serverloc;
}
}
funNotinClass(){
echo $serverloc;
}
There is a Class contains 2 functiona "push()" and "otherFunction()" and there is independent function "funNotinClass()" and push() calls it. The class is for a web form in other page. When user click submit the form call the class and use the push() function. A weird thing I found is that the global var $serverloc is invisible to push() and funNotinClass()(they don't print out any thing), but otherFuction() which is a function just like puch() inside of the Aclass can just use the $serverloc(I dont even add global in front of it). How strange....anyone know what is the reason caused this?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
I read many information about the scope of a global var in php.
they all say a global var is defined outside of function or class and you can use it by using global this key word.
So this is my code
$serverloc='serverURL';
class Aclass{
function Afunction(){
global $serverloc;
echo $serverloc;
}
}
but when I run this class it didn't print anything out.
Is that because I did something wrong or global var just doesn't work this way. Since all the example I read before are just access a global var in functions directly not a function in a class
As per DaveRandom's comment - you haven't actually made an instance of an Aclass object.
This works and displays data as expected:
<?php
$serverloc='serverURL';
class Aclass{
global $serverloc;
function Afunction()
{
echo $serverloc;
}
}
$me = new Aclass();
$me->Afunction(); // output: serverURL
?>
Edit: DaveRandom seems to post asnwers as comments. Go Vote up some of his other answers, the rep belongs to him not me. I am his ghostwriter tonight.
If it is class globals you are after you could do like
class myClass
{
private $globVar = "myvariable";
function myClass()
{
return $this->globVar;
}
}
but when I run this class it didn't print anything out
You don't run classes, in the sense of executing them. A class is a just a data structure that holds data and functions related (called methods).
As most traditional data structures, you create instances of them (called objects), and then you execute actions on them. One way to execute actions on objects (instances of classes), is to pass a message for it to do something: that is calling a method.
So, in your case you could do:
$obj = new Aclass(); // create an object, instance of Aclass
$obj->Afunction(); // ask it to perform an action (call a method)
Having said that, sometimes you want to create a class only for grouping related functions, that never actually really share data within an object. Often they may share data through a global variable (eg.: $_SERVER, $_GET, etc). That may be the case of your design right there.
Such classes can have its methods executed without never instantiating them, like this:
Aclass::Afunction();
While relying on global variables is usually an indicator of quick'n dirty design, there are cases in which it really is the best trade-off. I'd say that a $serverlocation or $baseurl may very well be one of these cases. :)
See more:
The basics on classes and objects in the PHP manual
About the static keyword

Global Variable from Model

Not sure if it's global per se, but what I need is a variable that is set from within a model that is dynamically generated when the model gets called. However I need to set a variable that is accessible to multiple views being pulled in through the template to use the same variable.
Its an advertisement ID my clients sponsors have multiple ad spots per page example a 486x 60 and a 160x90 spot. But what I am trying to do is when there ID is pulled at random from the bunch I want all my ad spots to be the same sponsor.
Now I have tried going in my header.php view and defining a variable like
$adsIDvar = $this->modelname->sponsorids() and then in every view I have ad placement just using $varIDvar but it doesnt seem that any of the views inherate the variable. I have tried to find information on this but most people looking for a similar notation need hard coded variables like a site title for example.
I need something that can cross the barrier, and I'd prefer to avoid sessions/cookies as I want to avoid dealing with the whole Cookie thing in the UK as a good half of the viewers of the site are from the UK and I'd rather not have to go through the effort of saying this site uses cookies blah blah accept/decline just for this purpose. Besides, if they decline, that puts a kink in my work.
If you want to import a variable from the global scope, you need to use the global keyword. For example:
class SomeClass {
public function SomeFunction() {
global $adsIDvar; // now it is imported from the global scope
}
}
It's just my opinion but maybe a better approach would be to make a special class just for handling ad ids. I might try something like this:
class AdHelper {
public static $advertiser_id;
public static function getAdvertiserId() {
if (!isset(self::$advertiser_id)) {
self::selectAdvertiserId();
}
return self::$advertiser_id;
}
protected static function selectAdvertiserId() {
self::$advertiser_id = ....; // Implement this however you like, random or whatever
}
}
// you can call it from anywhere like:
$adsIDvar = AdHelper::getAdvertiserId();

Maintaining state between runs | Session Use

There are different way to run PHP code. For example user initiate reloads and user initiated ajax requests.
What it the best way to maintain state between these runs?
PHP does consider it separate runs. Two things:
Don't use globals... they're bad :) Consider making your "session" class a collection of static functions with the session_id as a static member var.
Simply create a new session class in your 2nd snippet:
$obj_ses = new session();
$obj_ses->activate('email', $this->_protected['email']);
The session id will be the same across all page views for that particular user, so creating a new session() in the second snippet will still refer to the same session you started in the first snippet.
Here's what a static implementation might look like:
// class names should be camel-cased
class SessionManager
{
protected static $session_id = null;
public static function start()
{
self::$session_id = session_start();
}
// ... and so on
}
// to use
SessionManager::start();
SessionManager::activate('email', $email);
That should really be all you need. There are certainly many ways to do this, but this ought to get you started :)

Storing user info in a session using an object vs. normal variables

I'm in the process of implementing a user authentication system for my website. I'm using an open source library that maintains user information by creating a User object and storing that object inside my php SESSION variable. Is this the best way to store and access that information?
I find it a bit of a hassle to access the user variables because I have to create an object to access them first:
$userObj = $_SESSION['userObject'];
$userObj->userId;
instead of just accessing the user id like this how I would usually store the user ID:
$_SESSION['userId'];
Is there an advantage to storing a bunch of user data as an object instead of just storing them as individual SESSION variables?
ps - The library also seems to store a handful of variables inside the user object (id, username, date joined, email, last user db query) but I really don't care to have all that information stored in my session. I only really want to keep the user id and username.
I think that logically grouping related data together under one key is best, it couples the relevant data with a common parent, it also gives you more wiggle room with regards to key names, so you could have $_SESSION['user']->id opposed to $_SESSION['user_id'], allows you to have property name context, so you don't have to provide the context in the key name as you would with a user_* key
I also think that there is a bigger concept that comes into play here, when you use user_* you are pretty much saying that anything with the key name user_* will be associated with a user. This is not a good way to organize objects IMO. However, when you use a user key and stick all of the associated data underneath it so to speak, then you have a much cleaner top level and a real nested data hierarchy as opposed to a linear one.
Why don't you create a session wrapper class that handles the accessing and storing of data? This will produce much cleaner code and abstract so changes to storing methods down the line with be pretty easy.
Here's an example of a wrapper:
abstract class Session
{
private static $_started = false;
private static $_driver;
public static function start($driver = "native", $site = "default")
{
if(self::$_started === false)
{
require_once "drivers/" . $driver . ".php";
self::$_driver = new $driver($_site);
}
}
public static function set($key,$value)
{
self::$_driver->set($key,$value);
}
public static function get($key)
{
self::$_driver->get($key);
}
public static function remove($key)
{
self::$_driver->remove($key);
}
}
The above is only simple but you should get the idea, you would also have to create the native driver file that has the set of methods required, and they should store the session data accordingly.
Example of using the Session class like so:
Session::start("native");
/*
* Generic Code
*/
Session::set("key","value (:");
When fetching your "User" Object you can just do simple like so:
Session::get("userObj")->id;
Produces much cleaner code and larger scope issues.
After time goes by you can just create a new driver for storing in the database and then just change your driver from native to database.
Note: Storing objects in the database can be a little buggy especially if your code is not organized as loading the session before the user class is on scope then you can get partial objects in the session which will lead to lack of functionality.

Codeigniter: easiest way to use variables between models and controllers, models and models, controllers and controllers

Is this just impossible?
I thought I would clean up some of my code and put db queries in models only where they belong and put all the other code that belongs in controllers in controllers.
Now I keep getting undefined variable errors. Which is not a problem but I'm trying to work out how to call variables between files.
I would simply like the random hash generated at registration .. stored in a variable because that's the variable I use in the anchor for the "click here to activate account" link that is sent to users email.
I also use that same variable in the method that compares the uri hash that's at the end of the URL in their email with the one stored in the database.. in order for user to confirm their account and update "status" in database to 1(activated).
I would really appreciate some advice. I'm enjoying this learning process. Loosing sleep but enjoying it as it make me think logically.
You cannot access a variable if it's in a seperate file, instead you should set it in your class.
class User_model extends Model {
// Declare the foo variable
public $foo = "";
function blah() {
// You can set variable foo this way from any controller/model that includes this model
$this->foo = "dog";
// You can access variable foo this way
echo $this->foo;
}
}

Categories