I'd like to set the value of my static variable to a function. But the __construct never runs with static calls. So what's an alternate route I can do to set this variable so I can re-use it many times in my class?
function sayhey(){
return 'hey';
};
// my class i do control
class Class1 {
private static $myvar;
public function __construct(){
self::$myvar = sayhey();
}
public static function func1(){
echo '<pre>'; print_r(self::$myvar); echo '</pre>';
}
}// end class
// how can i make this work if the __construct never runs for static calls?
Class1::func1();
// obviously this works
//$class1 = new Class1();
//$class1->func1();
Try this
<?php
function sayhey(){
return 'hey';
};
// my class i do control
class Class1 {
private static $myvar;
public function __construct(){
self::$myvar = sayhey();
//echo '<pre>11 '; print_r(self::$get_cart_contents); echo '</pre>';
}
public static function func1(){
echo '<pre>';
self::$myvar = self::$myvar ?? sayhey();
print_r ( self::$myvar );
echo '</pre>';
}
}// end class
Class1::func1();
You need at some point to initialise the static property. As the constructor is useless for static methods, this 'replaces' the work done by creating an init() method (also static) which is called when self::$myvar is null (using self::$myvar ?? self::init()...
function sayhey(){
return 'hey';
};
// my class i do control
class Class1 {
private static $myvar;
public static function init(){
self::$myvar = sayhey();
return self::$myvar;
}
public static function func1(){
echo '<pre>'; print_r(self::$myvar ?? self::init()); echo '</pre>';
}
}// end class
// how can i make this work if the __construct never runs for static calls?
Class1::func1();
You can also save the function name in the variable instead of the result of the call.
function sayhey(){
return 'hey';
};
class Class1 {
private static $myvar;
public static function set($fct){
self::$myvar = $fct;
}
public static function func(){
$result = (self::$myvar)();
return $result;
}
}
Class1::set('sayhey');
echo Class1::func(); //hey
I suspect traits are better.
trait myfunctions{
public static function sayhey(){
return 'hey';
}
}
class Class1 {
use myfunctions;
}
class Class2 {
use myfunctions;
public static function fct1(){
return self::sayhey();
}
}
echo Class1::sayhey(); //hey
echo Class2::sayhey(); //hey
echo Class2::fct1(); //hey
Related
I've this trait class:
trait Example
{
protected $var;
private static function printSomething()
{
print $var;
}
private static function doSomething()
{
// do something with $var
}
}
And this class:
class NormalClass
{
use Example;
public function otherFunction()
{
$this->setVar($string);
}
public function setVar($string)
{
$this->var = $string;
}
}
But i'm getting this error:
Fatal error: Using $this when not in object context.
How can i solve this issue? I can't use properties on a trait class? Or this isn't really a good practice?
Your problem is connected with differences between class's methods/properties and object's.
If you define a property as static - you should access it through your class like classname/self/parent ::$property.
If not static - then inside static property like $this->propertie.
For example:
trait Example
{
protected static $var;
protected $var2;
private static function printSomething()
{
print self::$var;
}
private function doSomething()
{
print $this->var2;
}
}
class NormalClass
{
use Example;
public function otherFunction()
{
self::printSomething();
$this->doSomething();
}
public function setVar($string, $string2)
{
self::$var = $string;
$this->var2 = $string2;
}
}
$obj = new NormalClass();
$obj -> setVar('first', 'second');
$obj -> otherFunction();
Static function printSomething can't access not static propertie $var!
You should define them both not static, or both static.
Using $this when not in object context because of this code
$this->form_validation->set_rules('username','Username','required');
In the documentation is this example and understand it without problems
class Bar{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test();
The result is:
Bar::testPrivate
Foo::testPublic
But now redefine the test () method in the class foo
class Bar{
public function test() {
echo '<br>Im Bar::test';
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "<br>Bar::testPublic\n";
}
private function testPrivate() {
echo "<br>Bar::testPrivate\n";
}
}
class Foo extends Bar{
public function test() {
echo '<br>Im Foo::test';
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "<br>Foo::testPublic\n";
}
private function testPrivate() {
echo "<br>Foo::testPrivate\n";
}
}
$myFoo = new Foo();
$myFoo->test();
The result is:
Im Foo::test
Foo::testPrivate
Foo::testPublic
php allows me to override the private method testPrivate (), Why?
Why not? It's difficult to answer that question as it's just how PHP works. If you want to prohibit your methods from being overwritten then you can use the final keyword.
Additionally, in your example, if you do not declare the private method within Foo, you will get an error as Foo technically has no definition for that method. Extending classes have no visibility of any private properties or methods within their parent class.
Say object of class B is attribute of class A. How can I call method of object of class A from method of object of class B? What would be nice solution without passing object link?
Thanks!
Here goes code sample:
class A{
var $b;
function __construct(){
$this->b = new B();
}
function f1(){
$this->b->f3();
}
function f2(){
echo 'hello!';
}
}
class B{
function f3(){
// call f2() method in object $obj(not new A())
}
}
$obj = new A();
$obj->f1();
You can use a static function
public static function f2{
echo 'hello!';
}
with f3 defined as
function f3(){
A::f2();
}
This may not ultimately be the solution you want, however. See more info here.
The only way you can access that instance's function is if you inject it on the B object as a dependency. You can inject it within the constructor, like this:
<?php
class A {
protected $b;
public function __construct() {
$this->b = new B($this);
}
public function f1() {
$this->b->f3();
}
public function f2() {
echo 'hello!';
}
}
class B {
protected $a;
public function __construct($a) {
$this->a = $a;
}
public function f3() {
$this->a->f2();
}
}
$obj = new A();
$obj->f1();
So say I have the following code,
$obj = new foo();
echo $obj;
class foo {
public function __construct()
{
return 'a';
}
}
How do I make $obj echo the string 'a'?
How do I make $obj refer to or equal what is returned by the object/class?
Need to return a value from a __construct(), and also a normal private function within another class. For example:
$obj2 = new foo2();
echo $obj2;
class foo2 {
public function __construct()
{
bar();
}
private bar()
{
return 'a';
}
}
Thanks!
you can use the magic __toString() method to convert your class to a representing string.
You should not return something in your constructor, __toString() is automaticly called if you try to use your instance as string (in case of echo).
from php.net:
<?php
// Declare a simple class
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Hello');
echo $class;
?>
http://www.php.net/manual/en/language.oop5.magic.php#object.tostring
Constructors in PHP are more like initialisation functions; their return value is not used, unlike JavaScript for instance.
If you want to change the way objects are normally echoed you need to provide the magic __toString() method:
class foo
{
private $value;
public function __construct()
{
$this->value = 'a';
}
public function __toString()
{
return $this->value;
}
}
A private method that would return the value can be used in a similar manner:
class foo2
{
private function bar()
{
return 'a';
}
public function __toString()
{
return $this->bar();
}
}
Here's my code:
class Manual extends controller {
function Manual(){
parent::Controller();
$myVar = 'blablabla';
}
function doStuff(){
echo $myVar; // Doesn't work.
}
}
I've tried various methods to make it work, but I've can't get my head around it. What can I do?
Thanks
In your code, $myVar is local to each method.
Perhaps you meant $this->myVar?
You need to use the $this 'pointer'.
e.g.:
class Test
{
protected $var;
public function __construct()
{
$this->var = 'foobar';
}
public function getVar()
{
return $this->var;
}
};
class Manual extends controller {
private $myVar;
function Manual(){
parent::Controller();
$this->$myVar = 'blablabla';
}
function doStuff(){
echo $this->$myVar;
}
}
Even more OOP-like with Setters/Getters
class Manual extends controller {
private $myVar;
function Manual(){
parent::Controller();
setMyVar('blablabla');
}
function doStuff(){
echo getMyVar();
}
function getMyVar() {
return $this->myVar;
}
function setMyVar($var) {
$this->myVar = $var;
}
function doStuff(){
echo $this->myVar;
}
The variable $myVar should be property of a class, and you can not do:
echo $myVar;
You should do:
$this->myVar;
As written, $myVar is local to both methods.
You need to declare $myVar as a property in the class body
protected $myVar;
and then use the pseudo variable $this to access the property in methods, including the constructor
$this->myVar;
$myVar field must be declarated as public/protected in the parent class or declarated in the descedent class, and in yours doStuff() method you must write $this->myVar not the $myVar