I am trying to create a library for codeigniter that uses pthread, everything works fine but when i want to assign a value to an array this don't work with traditional $a['key'] = 'val';
Small Test Exemple : ( updated )
class Test {
protected $core;
protected $stack;
public function init(){
$this->stack = new Test_Stack();
$this->core = new Test_Core($this->stack);
}
public function do_test(){
return $this->core->assign();
}
}
class Test_Stack extends Stackable {
protected $a;
function __construct(){
$this->a = array();
}
protected function test(){ // Call from other class extends Threads
$this->a['key1'] = 'NOWORK';
print_r($this->a); // THIS RETURN NOTHING
$this->a = array_merge($this->a, array('key1' => 'WORK'));
print_r($this->a); // NOW THIS GOOD RETURN Key1..
}
public function run(){}
}
class Test_Core {
protected $thread;
protected $stack;
function __construct($s){
$this->stack = $s;
}
public function assign(){
$this->thread = new Test_Thread($this->stack);
$this->thread->start();
$this->thread->join();
}
}
class Test_Thread extends Thread{
protected $stack;
function __construct($s){
$this->stack = $s;
}
public function run(){
$this->stack->test();
}
}
I write this basic code without testing but it's the same structure of my lib and need this to extends test_stack and add or change test function for exemple.
Even if works now, I would understand why I can't assign my array normally ?
Or rather, what am I doing wrong?
Working in Mine :
class Stack {
protected $a;
function __construct(){
$this->a = array();
}
function test(){
$this->a['key1'] = 'NOWORK';
print_r($this->a); // THIS RETURN NOTHING
$this->a = array_merge($this->a, array('key1' => 'WORK'));
print_r($this->a); // NOW THIS GOOD RETURN Key1..
}
}
$obj = new Stack();
$obj->test();
Output :
Array
(
[key1] => NOWORK
)
Array
(
[key1] => WORK
)
OK array isn't thread safe, should be used stackable, this do the trick :
Libraries/Test.php :
class Test {
protected $core;
protected $stack;
public function init(){
$this->stack = new Test_Stack();
$this->core = new Test_Core($this->stack);
}
public function do_test(){
$this->core->assign();
$this->core->assign();
$this->core->assign();
}
public function get_a(){
return $this->core->get_a();
}
}
class Test_Array_Stack extends Stackable {
public function run(){}
}
class Test_Stack extends Stackable {
protected function test($a){
$a[] = 'WORK';
}
public function run(){}
}
class Test_Core {
protected $thread;
protected $stack;
protected $a;
function __construct($s){
$this->stack = $s;
$this->a = new Test_Array_Stack();
}
public function assign(){
$this->thread = new Test_Thread($this->stack, $this->a);
$this->thread->start();
$this->thread->synchronized(function($thread){
$thread->wait();
}, $this->thread);
return $this->a;
}
public function get_a(){
return $this->a;
}
}
class Test_Thread extends Thread{
protected $stack;
protected $a;
function __construct($s, $a){
$this->stack = $s;
$this->a = $a;
}
public function run(){
$this->stack->test($this->a);
$this->synchronized(function($thread){
$thread->notify();
}, $this);
}
}
You can extends Test_Stack to create lib extension more useful for my project, like this on other file Test_Info.php :
require_once APPPATH.'libraries/Test.php';
class Test_Info extends Test {
function init(){
$this->stack = new Test_Info_Stack();
$this->core = new Test_Core($this->stack);
}
}
class Test_Info_Stack extends Test_Stack {
protected function test($a){
parent::test($a);
$a[] = 'INFO';
}
}
And usage on controller:
function index(){
//without extension
$this->load->library('Test');
$this->test->init();
$this->test->do_test();
print_r($this->test->get_a());
//with extension
$this->load->library('Test_Info');
$this->test_info->init();
$this->test_info->do_test();
print_r($this->test_info->get_a());
}
It took me some time, i hope it will help someone and LuckyBurger thank you for the explanation link.
Related
I am noob in PHP because I am mostly do .NET/Java. In code base I am working, I have,
class SomeOtherBaseClass{
public $prop2;
public function __construct(string $prop3)
{
$this->prop2 = $prop3;
}
public function __toString()
{
return $this->prop2 . ' '. $this->prop2;
}
}
class SomeClass
{
public function __toString()
{
return $this->prop1 . ' '. $this->prop1;
}
public $prop1;
public function someMethod() : SomeOtherBaseClass
{
return $this->createClass();
}
public function __construct()
{
$this->prop1 = 'foo';
}
private function createClass(
): SomeOtherBaseClass {
return new class(
$this->prop1
) extends SomeOtherBaseClass {
};
}
}
$class = new SomeClass();
echo $class;
echo $class->someMethod();
Why I am getting error that prop1 not found. Clearly createClass function is part of SomeClass which have prop1. Why I cannot access prop1 inside createClass?
It's because $prop1 has no value or meaning.
You can add a __construct() function to resolve your issue:
public function __construct()
{
$this->prop1 = 'foo';
}
now when you call this class (e.g. $foo = new SomeClass();):
$prop1 has a value of foo which can be used in your functions:
public function echoProp()
{
echo $this->prop1; # will output foo
}
Note: This is just an explanation answer - not a copy/paste solution - but the principles are all here for you to use in your code.
Let me know if this wasn't what you were looking for :)
Edit:
if prop1 exists in SomeOtherClass, when you construct you can do
public function __construct()
{
$this->class = new SomeClass();
$this->prop1 = $this->class->prop1;
}
Here is the code of registry I'd like to use. But static doesn't work as it should. In this example it always returns 2 (while 1 is expected). What can it be?
<?php
class CommonRegistry{
protected static $register;
public static function show()
{
return static::$register;
}
}
class NewRegister extends CommonRegistry{
public function __construct($num)
{
static::$register = $num;
}
}
class AnotherRegister extends CommonRegistry
{
public function __construct($num)
{
static::$register = $num;
}
}
$a = new NewRegister(1);
$b = new AnotherRegister(2);
var_dump(NewRegister::show());
Trying to use objects that extend singletone, but something I can't do.
How to call method from extended class?
How to show 13 non 12 with singleton?
class SingletonTest
{
protected static $_instance;
private function __construct(){}
private function __clone(){}
public static function getInstance() {
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function test2(){
return 12;
}
}
class ExtendSingleton extends SingletonTest
{
public function test2() {
return 13;
}
}
$b = ExtendSingleton::getInstance();
echo $b->test2(); //12
You will get what you want if you use static binding keyword "static" instead of "self"
class SingletonTest
{
protected static $_instance;
private function __construct(){}
private function __clone(){}
public static function getInstance() {
if (null === static::$_instance) {
static::$_instance = new static();
}
return static::$_instance;
}
public function test2(){
return 12;
}
}
class ExtendSingleton extends SingletonTest
{
public function test2() {
return 13;
}
}
$b = ExtendSingleton::getInstance();
echo $b->test2(); //13
$a = SingletonTest::getInstance();
echo $a->test2(); //13
exit;
But as You see in the above example this way a class which You will call first to "getInstance" will take place to store its instance in the $_instance field.
There is no way to create a base singleton class and inherit singleton behavior.
public static function getInstance()
{
static $instances = array();
$calledClass = get_called_class();
if (!isset($instances[$calledClass]))
{
$instances[$calledClass] = new $calledClass();
}
return $instances[$calledClass];
}
So this should work for you:
(So first normally functions are public so you can use them if you extend from another class! And the you have to make an object from ExtendSingleton not from SingletonTest since ExtendSingleton exdend's -> SingletonTest and not the other way.)
<?php
class SingletonTest {
protected static $_instance;
public function __construct() {
}
public function __clone() {
}
public static function getInstance() {
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function test2(){
return 12;
}
}
class ExtendSingleton extends SingletonTest {
public function test2() {
return 13;
}
}
$b = new ExtendSingleton();
echo $b->test2(); //13
?>
Output:
13
I've tested bicccio's solution and it works
class SingletonTest
{
protected static $_instances = [];
private function __construct(){}
private function __clone(){}
public static function getInstance()
{
$calledClass = get_called_class();
if (!isset(self::$_instances[$calledClass]))
{
self::$_instances[$calledClass] = new $calledClass();
}
return self::$_instances[$calledClass];
}
public function test2(){
return 12;
}
}
class ExtendSingleton extends SingletonTest
{
public function test2() {
return 13;
}
}
$b = ExtendSingleton::getInstance();
echo $b->test2(); //13
$a = SingletonTest::getInstance();
echo $a->test2(); //12
You can extend singleton class in php using late static binding the whole process is well discussed in this question.
Creating the Singleton design pattern in PHP5
<?php
class FirstClass{
public static $second;
public static $result = 'not this =/';
public function __construct(){
$this->result = 'ok';
$this->second = new SecondClass();
}
public function show(){
echo $this->second->value;
}
}
class SecondClass extends FirstClass{
public $value;
public function __construct(){
$this->value = parent::$result; //Make it get "ok" here
}
}
$temp = new FirstClass();
$temp->show(); //It will show: "not this =/"
?>
How can I make it to print "ok"?
I mean, the SecondClass should know what FirstClass set as result, see?
Replace $this->result = 'ok'; with self::$result = 'ok'; in FirstClass constructor.
Btw, the code is terrible. You're mixing static and instance variables, and extend classes but don't use benefits extension provides.
you need to reference the static as self::$result in the first class.
Below should do what you want...
<?php
class FirstClass{
public static $second;
public static $result = 'not this =/';
public function __construct(){
self::$result = 'ok';
$this->second = new SecondClass();
}
public function show(){
echo $this->second->value;
}
}
class SecondClass extends FirstClass{
public $value;
public function __construct(){
$this->value = parent::$result; //Make it get "ok" here
}
}
$temp = new FirstClass();
$temp->show(); //It will show: "not this =/"
?>
I would like to have a base class with basic properties and functions, so I dont have to define them in all child classes.
I use php 5.3.3.
Is this impossible ?
class A {
private $debug;
private $var;
protected function setVar($str) {
$this->debug = 'Set by function `'. MAGIC_HERE .'` in class `'. get_called_class() .'`.';
$this->var = $str;
return true;
}
protected function getVar() {
return $this->var;
}
protected function getDebug() {
return $this->debug;
}
}
class B extends A {
public function __construct() {
$this->doSomething();
}
public function doSomething() {
$this->setVar('my string');
}
}
$myobj = new B();
$myobj->getDebug();
// expected output "Set by function `doSomething` in class `B`."
<?php
class A {
private $debug;
private $var;
protected function setVar($str) {
$this->debug = 'Set by function `'. MAGIC_HERE .'` in class `'. get_called_class() .'`.';
$this->var = $str;
return true;
}
protected function getVar() {
return $this->var;
}
// Notice the public here, instead of protected //
public function getDebug() {
return $this->debug;
}
}
class B extends A {
public function __construct() {
$this->doSomething();
}
public function doSomething() {
$this->setVar('my string');
}
}
$myobj = new B();
echo $myobj->getDebug();
// expected output "Set by function `doSomething` in class `B`."
You had just two small issues. A::getDebug needed to be public to be accessible from the outside and you forgot to output the return of A::getDebug.
See the debug_backtrace function. Note this function is expensive, so you should disable those debug features in production.
Is this no good for you?
I'm not running 5.3 locally, so I had to switch out get_called_class() but you could still use it. Should have made that clear, sorry.
class A {
private $debug;
private $var;
protected function setVar($str, $class) {
$this->debug = 'Set by function `` in class `'. $class .'`.';
$this->var = $str;
return true;
}
protected function getVar() {
return $this->var;
}
public function getDebug() {
return $this->debug;
}
}
class B extends A {
public function __construct() {
$this->doSomething();
}
public function doSomething() {
$this->setVar('my string', __CLASS__);
}
}
$myobj = new B();
echo $myobj->getDebug();