Static function of a class - php

I have a code here,
class someClass {
public $someMember;
public function __construct() {
$this->someMember = 1;
}
public static function getsomethingstatic() {
return $this->someMember * 5;
}
}
$obj = new someClass();
echo $obj::getsomethingstatic();
and return an error, I know it has something to do with static but I couldn't find good explanation. I know how to fix this, I'm just looking for an explanation which will add to my understanding.
Anyone?

A static function ($obj::) cannot return/use a non-static ($this) class property, you'd have to make getsomethingstatic non-static to return the variable or make the variable static and update your other functions respectively.
As $this refers to the instance in question and static functions by definition are used outside of the instance it is not possible to mix.
ProTip
In the future, please include the error in the OP. It was easy to spot the error in this question but it might not have been in another case so included the required information speeds up the process.

You don't use the object accessor -> within Static methods. Use the Scope-Resolution Operator :: instead; prefixing it with either self or static as shown below. However be sure to use only static member variables/properties within Static methods as well...
class someClass {
public static $someMember;
public function __construct() {
self::$someMember = 1;
// OR
static::$someMember = 1;
}
public static function getsomethingstatic() {
return self::$someMember * 5;
// OR
return static::$someMember * 5;
}
}
// TO CALL A STATIC METHOD OF A CLASS,
// YOU NEED NOT INSTANTIATE THE CLASS...
// SIMPLY CALL THE METHOD DIRECTLY ON THE CLASS ITSELF....
echo someClass::getsomethingstatic();

Related

Accessing a public/private function inside a static function?

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();

Singleton access / PHP Magic method __toString/ printing a static object

what I'm trying to achieve (PHP 5.3) is to have an accessor to my representation of, for example, the HTML Body of a page. Instead of echoing everything directly it should be added to an array of entries in that singleton. Example: myBodyClass::add('<h1>Title</h1>');
add() is declared as public static function add($strEntry) {}
Now should I just add them to a static array $entries like self::$entries[] = $strEntry; (class VersionB) or should I use an instance like self::getInstance()->entries[] = $strEntry;? (class VersionA) (whereby getInstance() would of course instanciate ´...new self;´ if necessary)
I don't quite understand the difference yet, I'm afraid.
The second part of my question is how to print the object. The PHP manual is a bit thin about why __toString() cannot be static - but then again I would understand a parser to have a problem distinguishing echo myBodyClass from a constant (so is that the reason?)
Ideally I would like to call add() as often as needed to add all parts of the body, and then use something like echo myHeaderClass, myBodyClass, myFooterClass; at the end of the script, which should invoke the __toString() methods within the classes.
Thanks for pointing me into the correct direction.
Code Example
class VersionA
{
private static $instance = null;
private $entries = array();
private final function __construct(){}
private final function __clone(){}
private static final function getInstance()
{
if (self::$instance === null) :
self::$instance = new self;
endif;
return self::$instance;
}
public static function add($sString)
{
self::getInstance()->entries[] = $sString;
}
public static function getHtml()
{
return implode("\r\n", self::getInstance()->entries);
}
}
class VersionB
{
private static $entries = array();
private final function __construct(){}
private final function __clone(){}
public static function add($sString)
{
self::$entries[] = $sString;
}
public static function getHtml()
{
return implode("\r\n", self::$entries);
}
}
(Copied from comments, as requested by OP...)
You're missing the point of a singleton. There is a difference between a singleton object and a static class. If you want to use methods that act on an object (like __toString()), then you need it to be an object; a static class isn't good enough. If you want to avoid calling getInstance all the time, then set a variable to the object, and pass it around everywhere like you would with other objects, per the Dependency Injection pattern. That would probably be best practice advice anyway.
The thing with a static class is that it isn't really OOP; it's just a bunch of global functions with a shared class name. One may as well use plain functions with a namespace declaration.
But the main reason for using a genuine singleton is swappability. Assuming you follow my advice above and create a single reference to the object that you pass around your code, it becomes a lot easier to swap in an alternative object since you don't have the hard-coded class name being referenced all over the place. This makes it a lot easier to write decent unit tests for your code that uses the class.
Hope that helps.
You should probably not use a static add method.
The idea of a singleton is that you create a single instance of a class so that external objects can interact with that instance. That means that your add method should not be static.
You could do something like:
class MyBodyClass
{
protected $entries = array();
protected $instance;
public static function getInstance()
{
if (is_null($this->instance)) {
$this->instance = new self();
}
return $this->instance;
}
private function __construct() {}
public function add($strEntry)
{
$this->entires[] = $strEntry;
}
}
And call it like this:
MyBodyClass::getInstance()->add('<h1>blah</h1>');
Something like this should work:
class MySingleton
{
public static function getInstance()
{
static $inst = null;
if ($inst === null) {
$inst = new MySingleton();
}
return $inst;
}
private function __construct() { }
public static function add() {}
public function __toString() {
echo 'Something';
}
}
$body = MySingleton::getInstance();
$body::add('Something');
echo $body;

how to make object public to all function in a class?

I've created a class that calls an object in the "__construct" how can i make this object available through out the class.
class SocialMedia { function __construct() { $object = "whatever"; } }
how can I access $object in the other functions (which are static) from with in the class.
I've tried to use "$this->object" but I get an error "$this when not in object context" when I try to call it from my other static functions.
Use
self::$object = 'whatever'
instead and read the PHP Manual on the static keyword
On a sidenote, statics are death to testability, so you might just was well forget what you just learned and use instance variables instead.
Try defining your object inside the scope of the class, right above the function. So, as an example:
class SocialMedia { public $object; function __construct() { $object = "whatever"; } }
Or you could try defining it as "public static" instead of just "public". As an example, this:
class SocialMedia { public static $object; function __construct() { $object = "whatever"; } }
make it static:
class SocialMedia {
protected static $object;
function __construct() {
self::$object = "whatever";
}
}
If $object is not static then you have a problem. You need to be able to refernce a specific instance of the class. Youll need to pass the actual instance of SocialMedia to its static method or come up with some other shenanigans:
public static function someMethod(SocialMedia $instance, $args)
{
// do stuff with $instance->object and $args
}
public function methodThatUsesStaticMethod($args)
{
self::someMethod($this, $args);
}
If $object is static then you can use the scope resolution operator to access it as others have mentioned:
public static $object;
public static function someMethod($args)
{
$object = self::$object;
// do stuff with $object and $args
}
But then you have another issue... What happens if no instance of SocialMedia has been created yet and so SocialMedia::$object is not yet set?
You could make your class a singleton (OOP Patterns in PHP Manual) but that really isn't any better solution if you want testability and/or dependency injection. No matter how you suggarcoat it you are after a global variable and sooner or later you'll find out all the troubles they bring.

call a static method inside a class?

how do i call a static method from another method inside the same class?
$this->staticMethod();
or
$this::staticMethod();
self::staticMethod();
More information about the Static keyword.
Let's assume this is your class:
class Test
{
private $baz = 1;
public function foo() { ... }
public function bar()
{
printf("baz = %d\n", $this->baz);
}
public static function staticMethod() { echo "static method\n"; }
}
From within the foo() method, let's look at the different options:
$this->staticMethod();
So that calls staticMethod() as an instance method, right? It does not. This is because the method is declared as public static the interpreter will call it as a static method, so it will work as expected. It could be argued that doing so makes it less obvious from the code that a static method call is taking place.
$this::staticMethod();
Since PHP 5.3 you can use $var::method() to mean <class-of-$var>::; this is quite convenient, though the above use-case is still quite unconventional. So that brings us to the most common way of calling a static method:
self::staticMethod();
Now, before you start thinking that the :: is the static call operator, let me give you another example:
self::bar();
This will print baz = 1, which means that $this->bar() and self::bar() do exactly the same thing; that's because :: is just a scope resolution operator. It's there to make parent::, self:: and static:: work and give you access to static variables; how a method is called depends on its signature and how the caller was called.
To see all of this in action, see this 3v4l.org output.
This is a very late response, but adds some detail on the previous answers
When it comes to calling static methods in PHP from another static method on the same class, it is important to differentiate between self and the class name.
Take for instance this code:
class static_test_class {
public static function test() {
echo "Original class\n";
}
public static function run($use_self) {
if($use_self) {
self::test();
} else {
$class = get_called_class();
$class::test();
}
}
}
class extended_static_test_class extends static_test_class {
public static function test() {
echo "Extended class\n";
}
}
extended_static_test_class::run(true);
extended_static_test_class::run(false);
The output of this code is:
Original class
Extended class
This is because self refers to the class the code is in, rather than the class of the code it is being called from.
If you want to use a method defined on a class which inherits the original class, you need to use something like:
$class = get_called_class();
$class::function_name();
In the later PHP version self::staticMethod(); also will not work. It will throw the strict standard error.
In this case, we can create object of same class and call by object
here is the example
class Foo {
public function fun1() {
echo 'non-static';
}
public static function fun2() {
echo (new self)->fun1();
}
}
call a static method inside a class
className::staticFunctionName
example
ClassName::staticMethod();

How to access a private member inside a static function in PHP

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.

Categories