<?php
class A {
var $varA;
function funcA() {
$this->varA='AAAA';
$bbb = new B();
$bbb->funcB();
}
}
class B {
function funcB() {
//### Is there any way to get value of $varA from here?
}
}
echo $aaa->funcA;
?>
Please see the code above. Is there any way to get value of $varA from funcB()? I know about global and I know I can pass it or add var $varB; to the B class and set it. I am asking is there any standard way (syntax) to just get the value?
You could make the variable in class A public and static, which would make it accessible using A::$varA.
class A {
public static $varA;
function funcA() {
self::$varA = 'AAAA';
$bbb = new B();
$bbb->funcB();
}
}
class B {
function funcB() {
// Get value of $varA from A statically
echo A::$varA;
}
}
However, I wouldn't recommend doing it this way, as order of operations becomes more important. I'd look at traditional public getters/setters and take a look at possible desing flaws leading you to needing this solution in the first place.
Related
I try to create some sort of setup class, like global values for the page.
The PHP-code
class globals
{
public $page;
public function __construct()
{
}
public function set_page($value)
{
$this->page = $value; // Maybe from a database
}
}
class get
{
public function page()
{
$globals = new globals();
return $globals->page;
}
}
$globals = new globals();
$globals->set_page('My value');
echo get::page(); // Short function to be in a template
Question
My class forget the value I set. Why is that?
Do I have to use global variables?
Is this the correct approach for the problem?
The variable is set on an object, not on a class.
For each class, you can instantiate multiple objects. Each of those have their own variable scope.
Edit:
I forgot to include the easiest, and least verbose solution to your problem. AFAIK, you're looking for a way to check what page you're on. Constants will do just that:
defined('MY_CURRENT_PAGE') || define('MY_CURRENT_PAGE','My Value');
//use anywhere like so:
echo 'Currently on page: '.MY_CURRENT_PAGE;
My class forget the value I set. Why is that?
Quite simple: your page member function isn't static, yet you call it as though it is: get::page(). Even if you were to fix this, you're creating a new instance in the page method, but you're not preserving a reference too it anywhere, so each page call will create a new globals instance, that has nothing set.
Do I have to use global variables?
No, unless you're Really desperate, never use globals
Is this the correct approach for the problem?
No, if it doesn't work, it's not correct (IMHO).
Well, what is, you might ask. There are several ways to go about this:
class globals
{
public static $page = null;//make this static, meaning all instances will share this var
public function set_page($value)
{
self::$page = $value; // Maybe from a database
}
}
class get
{
private $_globalsInstance = null;
public function __construct(globals $instance = null)
{
$this->_globalsInstance = $instance;
}
private function _getGlobals()
{
if (!$this->_globalsInstance instanceof globals)
{
$this->_globalsInstance = new globals();
}
return $this->_globalsInstance;
}
public function page()
{
return $this->_getGlobals()::$page;
}
}
Personally, however, I wouldn't work like this, I'd just pass my instances to wherever I need them (as arguments to functions/methods or just instantiate them in a scope that will be accessible:
class globals
{
public $page = null;//make this static, meaning all instances will share this var
public function set_page($value)
{
$this->page = $value; // Maybe from a database
}
}
$page = new globals();
$page->set_page('foobar');
someFunction($page);
$someObject->renderPage($page);
require_once('specificScript.php');
//inside required script:
echo $page->page;
Do I have to use global variables?
Not, if your can use PHP 5.3
Is this the correct approach for the problem?
Better to use a generic class for this, or use static properties of objects
<?php
class globals
{
public static $page;
public function __construct()
{
}
public function set_page($value)
{
self::$page = $value; // Maybe from a database
}
}
class get
{
public static function page()
{
return globals::$page;
}
}
$globals = new globals();
$globals->set_page('My value');
echo get::page(); // Short function to be in a template
P.S.
But this is not a nice approach
$globals there
class get
{
public function page()
{
$globals = new globals();
return $globals->page;
}
}
and there
$globals = new globals();
$globals->set_page('My value');
are different inctances of globals class.
One of the solutions is to make $page var static
public static $page;
I hope this helps
UPD:
Also you might apply Singleton to globals class and request for its insnance instead of creating new one directly:
globals::getInstance()->setPage('Page');
and
return globals::getInstance()->getPage();
In this case $page doesn't have to be static.
I'm not sure the other answers are very clear. You have created 2 classes. As such they have different scopes. As writen you can't access the original variable $page from the get class because it's outside the scope. Your page function in fact creates a new version of the object $globals without $page set. Normally you would place both your set and get functions in the initial object/class. Though it would be possible to use two class by calling the first class from the second and setting the page. Why you would want to do that I'm not sure.
if I were writing the class it would look like this.
class globals
{
public $page;
public function __construct()
{
}
public function set_page($value)
{
$this->page = $value; // Maybe from a database
}
public function get_page()
{
return $this->page;
}
}
Actually I would probably set page to private not public. As public I guess you don't need a get function.
for using methods of the class without object you must use static definition. but anyway you put value for one class object and try to get it from another...
Perhaps this will help you continue on your coarse:
class globals
{
public static $page;
public function set_page($value)
{
self::$page = $value; // Maybe from a database
}
}
class get extends globals
{
public function page()
{
$globals = new globals();
return parent::$page;
}
}
$globals = new globals();
$globals->set_page('My value');
echo get::page();
?>
I'm having some trouble creating a "super object" (similar to that of CodeIgniter) for a framework project I'm working on.
I want to make a super object that all of my other classes will run through. I did that, but it seems I am unable to use my super object's object in each of my classes without using the global keyword in every function.
I have something like this:
class a
{
function aa()
{
return 'class a';
}
}
class b
{
function bb()
{
$blah->a->aa();
}
}
class superobj
{
function loadClass($class)
{
$this->$class = new $class;
}
}
class blah extends superobj
{
function __construct()
{
$this->loadClass('a');
$this->loadClass('b');
}
}
$blah = new $blah;
So if I run this, I get an error because I can't access the aa method. If I put global $blah into the method bb, then it works (or at least in my real project it does, I dunno about this 5 second mockup hehe).
So is there any way to either make the $blah object global so that I don't need to reference it for every method, OR is there a better way to achieve what I am trying to do?
I'm not very good at OOP...
function bb() {
$blah->a->aa();
}
Indeed, as with any function, this function has no variables in its scope. $blah was neither passed to the function nor is it defined in the function, so it doesn't exist.
If your objects depend on an instance of blah to work, you should pass it to the constructor.
class b {
var $blah = null;
function __construct($blah) {
$this->blah = $blah;
}
function bb() {
$this->blah->foo();
}
}
$b = new b($instanceOfBlah);
Alternatively, use a static class that holds references to global objects and returns them on request (Registry pattern, like $blah = Registry::get('blah')).
Don't use global. Just don't.
I know you can assign a function's return value to a variable and use it, like this:
function standardModel()
{
return "Higgs Boson";
}
$nextBigThing = standardModel();
echo $nextBigThing;
So someone please tell me why the following doesn't work? Or is it just not implemented yet? Am I missing something?
class standardModel
{
private function nextBigThing()
{
return "Higgs Boson";
}
public $nextBigThing = $this->nextBigThing();
}
$standardModel = new standardModel;
echo $standardModel->nextBigThing; // get var, not the function directly
I know I could do this:
class standardModel
{
// Public instead of private
public function nextBigThing()
{
return "Higgs Boson";
}
}
$standardModel = new standardModel;
echo $standardModel->nextBigThing(); // Call to the function itself
But in my project's case, all of the information stored in the class are predefined public vars, except one of them, which needs to compute the value at runtime.
I want it consistent so I nor any other developer using this project has to remember that one value has to be function call rather then a var call.
But don't worry about my project, I'm mainly just wondering why the inconsistency within PHP's interpreter?
Obviously, the examples are made up to simplify things. Please don't question "why" I need to put said function in the class. I don't need a lesson on proper OOP and this is just a proof of concept. Thanks!
public $nextBigThing = $this->nextBigThing();
You can only initialize class members with constant values. I.e. you can't use functions or any sort of expression at this point. Furthermore, the class isn't even fully loaded at this point, so even if it was allowed you probably couldn't call its own functions on itself while it's still being constructed.
Do this:
class standardModel {
public $nextBigThing = null;
public function __construct() {
$this->nextBigThing = $this->nextBigThing();
}
private function nextBigThing() {
return "Higgs Boson";
}
}
You can't assign default values to properties like that unless that value is of a constant data type (such as string, int...etc). Anything that essentially processes code (such as a function, even $_SESSION values) can't be assigned as a default value to a property. What you can do though is assign the property whatever value you want inside of a constructor.
class test {
private $test_priv_prop;
public function __construct(){
$this->test_priv_prop = $this->test_method();
}
public function test_method(){
return "some value";
}
}
class standardModel
{
// Public instead of private
public function nextBigThing()
{
return "Higgs Boson";
}
}
$standardModel = new standardModel(); // corection
echo $standardModel->nextBigThing();
I'm trying to get data from a class in php5, where the data in the class is private and the calling function is requesting a piece of data from the class. I want to be able to gain that specific piece of data from the private variables without using a case statement.
I want to do something to the effect of:
public function get_data($field)
{
return $this->(variable with name passed in $field, i.e. name);
}
You could just use
class Muffin
{
private $_colour = 'red';
public function get_data($field)
{
return $this->$field;
}
}
Then you could do:
$a = new Muffin();
var_dump($a->get_data('_colour'));
<?php
public function get_data($field)
{
return $this->{$field};
}
?>
You may want to look at the magical __get() function too, e.g.:
<?php
class Foo
{
private $prop = 'bar';
public function __get($key)
{
return $this->{$key};
}
}
$foo = new Foo();
echo $foo->prop;
?>
I would be careful with this kind of code, as it may allow too much of the class's internal data to be exposed.
Does anyone know how to reset the instance variables via a class method. Something like this:
class someClass
{
var $var1 = '';
var $var2 = TRUE;
function someMethod()
{
[...]
// this method will alter the class variables
}
function reset()
{
// is it possible to reset all class variables from here?
}
}
$test = new someClass();
$test->someMethod();
echo $test->var1;
$test->reset();
$test->someMethod();
I know I could simply do $test2 = new SomeClass() BUT I am particularly looking for a way to reset the instance (and its variables) via a method.
Is that possible at all???
You can use reflection to achieve this, for instance using get_class_vars:
foreach (get_class_vars(get_class($this)) as $name => $default)
$this -> $name = $default;
This is not entirely robust, it breaks on non-public variables (which get_class_vars does not read) and it will not touch base class variables.
Yes, you could write reset() like:
function reset()
{
$this->var1 = array();
$this->var2 = TRUE;
}
You want to be careful because calling new someClass() will get you an entirely new instance of the class completely unrelated to the original.
this could be easy done;
public function reset()
{
unset($this);
}
Sure, the method itself could assign explicit values to the properties.
public function reset()
{
$this->someString = "original";
$this->someInteger = 0;
}
$this->SetInitialState() from Constructor
Just as another idea, you could have a method that sets the default values itself, and is called from within the constructor. You could then call it at any point later as well.
<?php
class MyClass {
private $var;
function __construct() { $this->setInitialState(); }
function setInitialState() { $this->var = "Hello World"; }
function changeVar($val) { $this->var = $val; }
function showVar() { print $this->var; }
}
$myObj = new MyClass();
$myObj->showVar(); // Show default value
$myObj->changeVar("New Value"); // Changes value
$myObj->showVar(); // Shows new value
$myObj->setInitialState(); // Restores default value
$myObj->showVar(); // Shows restored value
?>