Here is my code:
class {
$property = "something";
public static function myfunc() {
return $this->property;
}
}
but PHP throws this:
Using $this when not in object context
I know, the problem is using $this-> in a static method, ok I remove it like this:
class {
$property = "something";
public static function myfunc() {
return self::property;
}
}
But sadly PHP throws this:
Undefined class constant 'property'
How can I access a property which is out of a static method in it?
Generally, you should not do it. Static methods don't have an access to instance fields for a reason. You can do something like this, though:
// define a static variable
private static $instance;
// somewhere in the constructor probably
self::$instance = $this;
// somewhere in your static method
self::$instance->methodToCall();
Note that it will work only for a single instance of your class, since static variables are shared between all instances (if any).
You'll also need to add a bunch of validations (e.g. is $instance null?) and pay attention to all the implementation details that may cause you some troubles.
Anyway, I don't recommend this approach. Use it at your own risk.
Explaination
If you want to use a variable that wont change inside a class you don't want to instanciate, you need to use the static keyword in order to access it later in a method.
Also, you need a name for your class.
And finally, if you didn't specify a keyword as protected or public, you variable may be accessible outside the word, and so the method would be pointless. So I assume you need a protected value in order to use the method to call that variable.
Source-code
class Foo {
protected static $property = 'something';
public function getProperty() {
return self::$property;
}
}
echo Foo::getProperty(); /* will display : something */
echo Foo::$property; /* change from protected to public to use that syntax */
Documentation
PHP : classes.
PHP : static.
PHP : visibility.
Related
Due to the fact that you can not use $this-> inside a static functio, how are you supposed to access regular functions inside a static?
private function hey()
{
return 'hello';
}
public final static function get()
{
return $this->hey();
}
This throws an error, because you can't use $this-> inside a static.
private function hey()
{
return 'hello';
}
public final static function get()
{
return self::hey();
}
This throws the following error:
Non-static method Vote::get() should not be called statically
How can you access regular methods inside a static method? In the same class*
Static methods can only invoke other static methods in a class. If you want to access a non-static member, then the method itself must be non-static.
Alternatively, you could pass in an object instance into the static method and access its members. As the static method is declared in the same class as the static members you're interested in, it should still work because of how visibility works in PHP
class Foo {
private function bar () {
return get_class ($this);
}
static public function baz (Foo $quux) {
return $quux -> bar ();
}
}
Do note though, that just because you can do this, it's questionable whether you should. This kind of code breaks good object-oriented programming practice.
You can either provide a reference to an instance to the static method:
class My {
protected myProtected() {
// do something
}
public myPublic() {
// do something
}
public static myStatic(My $obj) {
$obj->myProtected(); // can access protected/private members
$obj->myPublic();
}
}
$something = new My;
// A static method call:
My::myStatic($something);
// A member function call:
$something->myPublic();
As shown above, static methods can access private and protected members (properties and methods) on objects of the class they are a member of.
Alternatively you can use the singleton pattern (evaluate this option) if you only ever need one instance.
I solved this by creating an object of the concerning class inside a static method. This way i can expose some specific public functions as static function as well. Other public functions can only be used like $object->public_function();
A small code example:
class Person
{
public static function sayHi()
{
return (new Person())->saySomething("hi");
}
public function saySomething($text)
{
echo($text);
}
private function smile()
{
# dome some smile logic
}
}
This way you can only say hi if using the static function but you can also say other things when creating an object like $peter->saySomething('hi');.
Public functions can also use the private functions this way.
Note that i'm not sure if this is best practice but it works in my situation where i want to be able to generate a token without creating an object by hand each time.
I can for example simply issue or verify a token string like TokenManager::getTokenToken(); or TokenManager::verifyToken("TokenHere"); but i can also issue a token object like $manager = new TokenGenerator(); so i can use functionality as $manager->createToken();, $manager->updateToken(updateObjectHere); or $manager->storeToken();
I have a class and it has some static, some not static methods. It has a static property. I'm trying to access that property inside all of it's methods, I can't figure out the right syntax.
What I have is this:
class myClass {
static public $mode = 'write';
static public function getMode() {
return myClass::$mode;
}
public function getThisMode() {
return $this->mode;
}
}
Can anyone tell me the actual syntax for this one?
For static properties use the following even inside a non static function
return self::$mode;
The reason for this is because the static propery exists whether an object has been instantiated or not. Therefore we are just using that same pre-existing property.
If you are outside of the class, make sure not to forget the $ or you will see this error as well. For example, make sure to call it like this:
$myClass = new myClass();
echo $myClass::$mode;
Not like this:
echo $myClass::mode;
I'm querying for the ID of a field by accessing a class function which someone has already put in place. The result is a object returned with protected member variables. I'm struggling to see how I can access the member variable values outside the class.
Accessing protected or private variables from public is incorrect (thats why they are protected or private). So better is to extend class and access required property or make getter method to get it publicaly. But if you still want to get properties without extending and if you are using PHP 5, you can acces with Reflection classes. Actually try ReflectionProperty class.
class Foo { protected $bar; }
$foo = new Foo();
$rp = new ReflectionProperty('Foo', 'bar');
$rp->setAccessible(true);
echo $rp->getValue($foo);
Here is the correct answer:
We can use bind() or bindTo methods of Closure class to access private/protected data of some class, for example:
class MyClass {
protected $variable = 'I am protected variable!';
}
$closure = function() {
return $this->variable;
};
$result = Closure::bind($closure, new MyClass(), 'MyClass');
echo $result(); // I am protected variable!
Just add a "get" method to the class.
class Foo
{
protected $bar = 'Hello World!';
public function getBar()
{
return $this->bar;
}
}
$baz = new Foo();
echo $baz->getBar();
I'm struggling to see how I can access the member variable values outside the class.
You can't: That's the whole point of protected.
You would have to extend the class with a method that fetches the variables for you.
You can't do this on an instantiated object, though - you would have to influence either the class definition, or change the class of the object at the point it was created.
You can access the protected member of class out side the class, also without extending protected member class, also without using any function of protected member class. Use below function to access it.
function getProtectedMember($class_object,$protected_member) {
$array = (array)$class_object; //Object typecast into (associative) array
$prefix = chr(0).’*’.chr(0); //Prefix which is prefixed to protected member
return $array[$prefix.$protected_member];
}
Please visit the Link to check more details about it.
with closure acces php protected variable for example
class ForExample
{
protected $var=122;
}
$call=function(){
echo $this->var;
};
$call->call(new ForExample());
If you really need that value:
Modify the class and add a public method that returns the value you want.
If you can't modify it, consider extending it and exposing the value there (it will be accessible, since it's protected). Prefer the first option, this is more of a hack.
Clearly, the class designer did not think you'd need the value you're trying to access, otherwise he would have added a method to retrieve it himself. Therefore, reconsider what you're doing.
DISCLAIMER: I don't remember how to code. It's been "a while". This may be completely off.
Well, first of all, if the members are protected, the original designer didn't intend for you to access them directly. Did you check for accessor methods?
If there aren't any, and you're conviced you really need these protected members, you could extend the type with accessors, cast, and get them that way. Like (in C++-like code)
class MyClass : public OldClass
{
public:
int getSomeValue() { return protectedValue; }
void setSomeValue(int value) { protectedValue=value; }
char* getOtherValue() { return otherProtectedValue; }
}
and then to use it
MyClass* blah = (MyClass*)TheirFactory->GiveMeAClass();
int yay=blah->getSomeValue();
You get the drift. Hope this works for you, Internet Explorer makes for a lousy compiler, so I haven't been able to test it.
}
I have the following class in PHP
class MyClass
{
// How to declare MyMember here? It needs to be private
public static function MyFunction()
{
// How to access MyMember here?
}
}
I am totally confused about which syntax to use
$MyMember = 0; and echo $MyMember
or
private $MyMember = 0; and echo $MyMember
or
$this->MyMember = 0; and echo $this->MyMember
Can someone tell me how to do it?
I am kind of not strong in OOPS.
Can you do it in the first place?
If not, how should I declare the member so that I can access it inside static functions?
class MyClass
{
private static $MyMember = 99;
public static function MyFunction()
{
echo self::$MyMember;
}
}
MyClass::MyFunction();
see Visibility and Scope Resolution Operator (::) in the oop5 chapter of the php manual.
This is a super late response but it may help someone..
class MyClass
{
private $MyMember;
public static function MyFunction($class)
{
$class->MyMember = 0;
}
}
That works. You can access the private member that way, but if you had $class you should just make MyFunction a method of the class, as you would just call $class->MyFunction(). However you could have a static array that each instance is added to in the class constructor which this static function could access and iterate through, updating all the instances. ie..
class MyClass
{
private $MyMember;
private static $MyClasses;
public function __construct()
{
MyClass::$MyClasses[] = $this;
}
public static function MyFunction()
{
foreach(MyClass::$MyClasses as $class)
{
$class->MyMember = 0;
}
}
}
Within static methods, you can't call variable using $this because static methods are called outside an "instance context".
It is clearly stated in the PHP doc.
<?php
class MyClass
{
// A)
// private $MyMember = 0;
// B)
private static $MyMember = 0;
public static function MyFunction()
{
// using A) // Fatal error: Access to undeclared static property:
// MyClass::$MyMember
// echo MyClass::$MyMember;
// using A) // Fatal error: Using $this when not in object context
// echo $this->MyMember;
// using A) or B)
// echo $MyMember; // local scope
// correct, B)
echo MyClass::$MyMember;
}
}
$m = new MyClass;
echo $m->MyFunction();
// or better ...
MyClass::MyFunction();
?>
Static or non-static?
Did you ever asked yourself this question?
You can not access non static parameters / methods from inside
static method (at least not without using dependency injection)
You can however access static properties and methods from with in non-static method (with self::)
Properties
Does particular property value is assign to class blueprint or rather to it instance (created object from a class)?
If the value is not tight to class instance (class object) then you could declare it as as static property.
private static $objectCreatedCount; // this property is assign to class blueprint
private $objectId; // this property is assign explicitly to class instance
Methods
When deciding on making a method static or non-static you need to ask yourself a simple question. Does this method need to use $this? If it does, then it should not be declared as static.
And just because you don't need the $this keyword does not
automatically mean that you should make something static (though the
opposite is true: if you need $this, make it non-static).
Are you calling this method on one individual object or on the class in general? If you not sure which one to use because both are appropriate for particular use case, then always use non-static. It will give you more flexibility in future.
Good practice is to always start to design your class as non-static and force static if particular us case become very clear.
You could try to declare your parameters as static... just so you can access it from static method but that usually is not what you want to do.
So if you really need to access $this from static method then it means that you need to rethink/redesign your class architecture because you have don it wrong.
I have a variable on the global scope that is named ${SYSTEM}, where SYSTEM is a defined constant. I've got a lot of classes with functions that need to have access to this variable and I'm finding it annoying declaring global ${SYSTEM}; every single time.
I tried declaring a class variable: public ${SYSTEM} = $GLOBALS[SYSTEM]; but this results in a syntax error which is weird because I have another class that declares class variables in this manner and seems to work fine. The only thing I can think of is that the constant isn't being recognised.
I have managed to pull this off with a constructor but I'm looking for a simpler solution before resorting to that.
EDIT
The global ${SYSTEM} variable is an array with a lot of other child arrays in it. Unfortunately there doesn't seem to be a way to get around using a constructor...
Ok, hopefully I've got the gist of what you're trying to achieve
<?php
// the global array you want to access
$GLOBALS['uname'] = array('kernel-name' => 'Linux', 'kernel-release' => '2.6.27-11-generic', 'machine' => 'i686');
// the defined constant used to reference the global var
define(_SYSTEM_, 'uname');
class Foo {
// a method where you'd liked to access the global var
public function bar() {
print_r($this->{_SYSTEM_});
}
// the magic happens here using php5 overloading
public function __get($d) {
return $GLOBALS[$d];
}
}
$foo = new Foo;
$foo->bar();
?>
This is how I access things globally without global.
class exampleGetInstance
{
private static $instance;
public $value1;
public $value2;
private function initialize()
{
$this->value1 = 'test value';
$this->value2 = 'test value2';
}
public function getInstance()
{
if (!isset(self::$instance))
{
$class = __CLASS__;
self::$instance = new $class();
self::$instance->initialize();
}
return self::$instance;
}
}
$myInstance = exampleGetInstance::getInstance();
echo $myInstance->value1;
$myInstance is now a reference to the instance of exampleGetInstance class.
Fixed formatting
You could use a constructor like this:
class Myclass {
public $classvar;
function Myclass() {
$this->classvar = $GLOBALS[SYSTEM];
}
}
EDIT: Thanks for pointing out the typo, Peter!
This works for array too. If assignment is not desired, taking the reference also works:
$this->classvar =& $GLOBALS[SYSTEM];
EDIT2: The following code was used to test this method and it worked on my system:
<?php
define('MYCONST', 'varname');
$varname = array("This is varname", "and array?");
class Myclass {
public $classvar;
function Myclass() {
$this->classvar =& $GLOBALS[MYCONST];
}
function printvar() {
echo $this->classvar[0];
echo $this->classvar[1];
}
};
$myobj = new Myclass;
$myobj->printvar();
?>
The direct specification of member variables can not contain any references to other variables (class {public $membervar = $outsidevar;} is invalid as well). Use a constructor instead.
However, as you are dealing with a constant, why don't you use php's constant or class constant facilities?
You're trying to do something really out-of-the-ordinary here, so you can expect it to be awkward. Working with globals is never pleasant, especially not with your dynamic name selection using SYSTEM constant. Personally I'd recommend you use $GLOBALS[SYSTEM] everywhere instead, or ...
$sys = $GLOBALS[SYSTEM];
... if you're going to use it alot.
You could also try the singleton pattern, although to some degree it is frowned upon in OOP circles, it is commonly referred to as the global variable of classes.
<?php
class Singleton {
// object instance
private static $instance;
// The protected construct prevents instantiating the class externally. The construct can be
// empty, or it can contain additional instructions...
protected function __construct() {
...
}
// The clone and wakeup methods prevents external instantiation of copies of the Singleton class,
// thus eliminating the possibility of duplicate objects. The methods can be empty, or
// can contain additional code (most probably generating error messages in response
// to attempts to call).
public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
public function __wakeup() {
trigger_error('Deserializing is not allowed.', E_USER_ERROR);
}
//This method must be static, and must return an instance of the object if the object
//does not already exist.
public static function getInstance() {
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}
//One or more public methods that grant access to the Singleton object, and its private
//methods and properties via accessor methods.
public function GetSystemVar() {
...
}
}
//usage
Singleton::getInstance()->GetSystemVar();
?>
This example is slightly modified from wikipedia, but you can get the idea. Try googling the singleton pattern for more information
I'd say the first two things that stand out to me are:
You don't need the brackets around the variable name, you can simply do public $system or public $SYSTEM.
While PHP may not always require it it is standard practice to encapsulate non-numeric array indexes in single or double quotes in case the string you're using becomes a constant at some point.
This should be what you're looking for
class SomeClass {
public $system = $GLOBALS['system'];
}
You can also use class constants which would instead be
class SomeClass {
const SYSTEM = $GLOBALS['system'];
}
This can be referenced within the class with 'self::SYSTEM' and externally with 'SomeClass::SYSTEM'.