Cannot override final method Exception::getPrevious() - php

I got CMS and trying to install it, but when i try to login i got error
Cannot override final method Exception::getPrevious()
Fatal error: Cannot override final method Exception::getPrevious() in C:\wamp\www\uis-online\application\exceptions\applicationException.php on line 41
Does anyboy have idea what cause this error
code in this file is
class ApplicationException extends Exception
{
protected $innerException;
/**
* Konstruktor
* #return unknown_type
*/
public function __construct($message, $code = 0, Exception $innerException = null)
{
parent::__construct($message, $code);
if (!is_null($innerException))
{
$this->innerException = $innerException;
}
}
public function getPrevious()
{
return $this->innerException;
}
// custom string representation of object
public function __toString() {
$exceptions_message = "";
if($this->innerException != null && $this->innerException->getMessage() != "") {
$exceptions_message = $this->innerException->__toString();
}
return $exceptions_message .__CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
}

As shown in the documentation the method you're trying to override is a final one.
final public Exception Exception::getPrevious ( void )
http://php.net/manual/en/exception.getprevious.php
According to the PHP manual you can't override final methods.
PHP 5 introduces the final keyword, which prevents child classes from overriding a method by prefixing the definition with final. If the class itself is being defined final then it cannot be extended.
http://php.net/manual/en/language.oop5.final.php

Related

I need this class to return a string value "error25" if it fails is it possible? - PHP [duplicate]

This question already has answers here:
Throw exception if value not passed to method
(2 answers)
PHP Error handling missing arguments
(3 answers)
Closed 7 months ago.
Hello everyone I have this class in php
<?php
namespace ExternalImporter\application\libs\pextractor\parser;
defined('\ABSPATH') || exit;
class Product {
public $link;
public $domain;
public $title;
public $description;
public $price;
public $currencyCode;
public $image;
public $oldPrice;
public $manufacturer;
public $inStock;
public $availability;
public $category;
public $condition;
public $ratingValue;
public $reviewCount;
public $features = array();
public $images = array();
public $reviews = array();
public $paused;
public $categoryPath = array();
public $extra = array();
}
However when this is called with a null value it gives me a fatal error.
I need that when this error occurs it returns the result: error25
I call the class like this in a function
public static function update(Product $newProduct, $product_id)
{
//code
}
In this example, $newProduct has the value of NULL, which is why it would generate an error in the function.
If I can return the error string error25 I could handle it.
Note: If the solution is to call the function, it is much better than editing the class itself.
My goal is to achieve something like this, but I'm not sure you can in PHP
public static function update(Product $newProduct ?: "error25", $product_id)
{
//code
}
Edit Possible solution
public static function update($newProduct, $product_id)
{
if (empty($newProduct)) {
# CALL Product $newProduct how to do it?
}
else {
$newProduct = NULL;
}
}
First of all your error occurs not because of your parameter $newProduct is null and not an instance of Product. It occurs because you have logic in your method definition. You can 't do that.
public static function update(Product $newProduct ?: "error25", $product_id)
This should never work. It 's a syntax error. It results in: PHP Parse error: syntax error, unexpected token "?", expecting ")". Please set your error reporting to the highest level, so that such basic errors are visible to you.
Checking against null or instance of a class
<?php
declare(strict_types=1);
namespace Marcel;
use Exception;
use stdClass;
class Foo
{
public static function bar(?stdClass $yadda): void
{
if ($yadda === null) {
throw new Exception('$yadda is not an instance of stdClass', 25);
}
// or ...
if (!$yadda instanceof stdClass) {
throw new Exception('$yadda is not an instance of stdClass', 25);
}
// everything okay at this point
$yadda->someProperty = 'I am a valid stdClass instance';
}
}
What happens here? Your static method takes a parameter that can either be an instance of stdClass or null. If $yadda is null an exception will be thrown with a message and a code.
Catching type errors
With PHP 8 you can catch type errors. That 's another solution to your problem.
<?php
declare(strict_types=1);
namespace Marcel;
use stdClass;
use TypeError;
class Test
{
public static function foo(stdClass $yadda): void
{
// some logic here
}
}
try {
Test::foo(null);
} catch (TypeErrror $error) {
var_dump($error->getMessage());
// Marcel\Test::foo(): Argument #1 ($bar) must be of type stdClass, null given
}
You can catch type errors in a try/catch block. If $yadda is something different than an instance of stdClass a type error will be thrown. You can handle this error in a catch block. With this solution you don 't have to declare your parameters as null or an instance of some class. You can just declare the type hint of a specific class and catch a type error when calling the static method.

What, why and how are Laravel service providers PHP

I started to wonder about what exactly is the purpose of service providers in Laravel, and why they work in the way they do. After searching through some articles,
the key points of service providers in my understanding are:
Simplifies object creation (Laravel What is the use of service providers for laravel)
Decoupling your code (r/laravel: When to use service providers?)
Dependency injection
Reduces technical debt
So it basically binds an implementation to an interface, and we can use it by
$app(MyInterface::class)
or something like that, and we can just change the implementation when needed, only in one place, and the rest of our code which depends on it won't break.
But i still can not grasp the concept, why they are the way they are, it seems overcomplicated. I peaked in to the code, it was certainly a ton of work to make Service Providers & Containers work, so there must be a good reason.
So to learn further, i tried to make my own, more simple version of it, which achieves the same goals. (i obviously lack a lot of info on this, and most probably missed some other goals)
My question is, why would this implementation would not satisfy the same use cases?
Service.php
namespace MyVendor;
/**
* Abstract class for creating services
*/
abstract class Service
{
/**
* Holds the instance of the provided service
*
* #var mixed
*/
private static mixed $instance = null;
/**
* Retrieves the instance of the provided service & creates it on-demand
*
* #return mixed
*/
public static function get(): mixed
{
if (self::$instance === null) {
self::$instance = static::instantiate();
}
return self::$instance;
}
/**
* A function which contains the service's object creation logic
*
* #return mixed
*/
abstract protected static function instantiate(): mixed;
}
Example implementation:
For the example, i chose an interface to parse environment variables, as i already had phpdotenv in my project as a dependency
Services/DotenvParser/DotenvParserInterface.php
namespace MyVendor\Services\DotenvParser;
/**
* This is the service interface i want to provide
*/
interface DotenvParserInterface
{
public function parse(string $directory, string $fileName = ".env"): array;
}
Now i will have 2 implementations of this class. I will pretend that a lot of my code already depends on DotenvParserInterface. An old, hacky one which "depends" on another thing, and the replacement for it which uses phpdotenv
A quick fake dependency:
Services/DotenvParser/Dependency.php
namespace MyVendor\Services\DotenvParser;
class Dependency
{
private bool $squeeze;
public string $bar;
public function __construct(string $foo, bool $squeeze)
{
$this->squeeze = $squeeze;
$this->bar = $foo;
if($this->squeeze){
$this->bar .= " JUICE";
}
}
}
Our old code:
Services/DotenvParser/OldDotenvCode.php
namespace MyVendor\Services\DotenvParser;
use BadMethodCallException;
use InvalidArgumentException;
class OldDotenvCode implements DotenvParserInterface
{
/**
* Our fake dependency
*
* #var Dependency
*/
private Dependency $foo;
private string $dir;
private string $fileName;
private string $contents;
private array $result;
public function __construct(Dependency $myDependency)
{
$this->foo = $myDependency;
}
/**
* Implementation of DotenvParserInterface
*
* #param string $directory
* #param string $fileName
* #return array
*/
public function parse(string $directory, string $fileName = ".env"): array
{
try{
$this->setDir($directory)->setFileName($fileName);
}catch(BadMethodCallException $e){
throw new InvalidArgumentException($e->getMessage(), 0, $e);
}
$this->getEnvContents();
$this->contents = $this->getEnvContents();
$this->result = [];
foreach(explode("\n", $this->contents) as $line){
$exploded = explode("=", $line);
$key = $exploded[0];
$value = (isset($exploded[1])) ? trim($exploded[1], "\r") : "";
if($this->foo->bar === "ORANGE JUICE"){
$value = trim($value, "\"");
}
$this->result[$key] = $value;
}
return $this->result;
}
#region Old, bad stuff
public function setDir(string $directory): self{
if(!\is_dir($directory)){
throw new InvalidArgumentException("Directory $directory is not a valid directory");
}
$this->dir = rtrim($directory, "/");
return $this;
}
public function setFileName(string $fileName): self{
if(empty($this->dir)){
throw new BadMethodCallException("Must call method setDir() first with a valid directory path");
}
$fileName = ltrim($fileName, "/");
if(!\file_exists($this->dir . "/" . $fileName)){
throw new InvalidArgumentException("File $fileName does not exist in provided directory {$this->dir}");
}
$this->fileName = $fileName;
return $this;
}
private function getFilePath(): string{
if(empty($this->fileName)){
throw new BadMethodCallException("Must call method setFileName() first");
}
return $this->dir . "/" . $this->fileName;
}
private function getEnvContents(): string{
return \file_get_contents($this->getFilePath());
}
public function setup(): void
{
$this->setDir($directory)->setFileName($fileName);
}
#endregion
}
Now, the phpdotenv version
Services/DotenvParser/phpdotenv.php
namespace MyVendor\Services\DotenvParser;
use Dotenv\Dotenv;
use InvalidArgumentException;
use Dotenv\Dotenv;
use InvalidArgumentException;
class phpdotenv implements DotenvParserInterface
{
public function parse(string $directory, string $fileName = ".env"): array
{
try{
Dotenv::createMutable($directory, $fileName)->load();
}catch(\Dotenv\Exception\InvalidPathException $e){
throw new InvalidArgumentException($e->getMessage(), 0, $e);
}
$result = $_ENV;
$_ENV = []; //Hehe
return $result;
}
}
Our service which we made from extending our Service class
Services/DotenvParser/DotenvParserService.php
namespace MyVendor\Services\DotenvParser;
use MyVendor\Service;
class DotenvParserService extends Service
{
// We can do this to make type hinting for ourselves
public static function get(): DotenvParserInterface
{
return parent::get();
}
protected static function instantiate(): DotenvParserInterface
{
$year = 2022;
// Some condition, to return one or another
if($year < 2022){
$dep = new \MyVendor\Services\DotenvParser\Dependency("ORANGE", true);
return new OldDotenvCode($dep);
}
return new phpdotenv();
}
}
And now, we can use it like this:
$dotenvparser = \MyVendor\Services\DotenvParser\DotenvParserService::get();
$result = $dotenvparser->parse(__DIR__);
var_dump($result);
// Outputs an array of our environment variables, yey!
We can also write tests for our services to see if anything breaks:
namespace MyVendorTest\Services\DotenvParser;
use InvalidArgumentException;
use MyVendor\Services\DotenvParser\DotenvParserInterface;
use MyVendor\Services\DotenvParser\DotenvParserService;
final class DotenvParserServiceTest extends \PHPUnit\Framework\TestCase
{
public function doesInstantiate(): void
{
$testParser = DotenvParserService::get();
$this->assertInstanceOf(DotenvParserInterface::class, $testParser);
}
public function testWorksFromValidDirNFile(): void
{
// The actual contents of a .env file
$testArray = [
"DEV_MODE" => "TRUE",
"BASE_HREF" => "http://localhost:8080/"
];
$testParser = DotenvParserService::get();
// phpdotenv loads every parent .env too and i was having none of it for this quick demonstration
$result = $testParser->parse(__DIR__."/../../../", ".env");
$this->assertEquals($testArray, $result);
}
public function testSetupFromInvalidDir(): void
{
$this->expectException(InvalidArgumentException::class);
$testParser = DotenvParserService::get();
$testParser->parse("i_am_a_dir_which_does_not_exist");
}
public function testSetupFromInvalidFile(): void
{
$this->expectException(InvalidArgumentException::class);
$testParser = DotenvParserService::get();
$testParser->parse(__DIR__, ".notenv");
}
}
So this ended up quite lenghty, but after having that Service class, you basically only need: An interface, at least one implementation of that interface, and a service class which instantiates an implementation of that interface, and optionally some tests for it. And, you can even do dependency injection with it (??) (circular dependencies would get us stuck in an endless loop), like this:
protected static function instantiate(): FooInterface
{
//BarService & AcmeService are extending our Service class
return new FooInterface(BarService::get(), AcmeService::get(), "ORANGE JUICE")
}
I am ready to absorb massive amounts of information
What other things Laravel's Service providers & containers do than i am aware of?
Why and how is it better than a simpler version, like this one?
Does my version really achieve at least those 4 key points i mentioned in the start?

Is there any way to execute data provider fuction after setupBeforeClass?

I have a unit test class in which I want to instantiate a object from another class in order to that I used setUpBeforeClass() fixtures of phpunit. So if I will use that recently instantiated object directly in test function then its working fine.
If i'll use this object into another function which had been created for data providers. So that object sets to null cause providers always execute first.
Is there a way to call dataProviders just before the test runs, instead?
require_once('Dashboard.php');
Class Someclass extends PHPUnit_Framework_TestCase {
protected static $_dashboard;
public static function setUpBeforeClass()
{
self::$_dashboard = new Dashboard();
self::$_dashboard->set_class_type('Member');
}
/**
* Test Org Thumb Image Existense
* param org profile image : array
* #dataProvider getOrgProfileImages
*/
public function testFieldValidation($a,$b){
//If I call that object function here it will give the result.
//$members = self::$_dashboard->get_members();
//var_dump($members); Printing result as expected
$this->assertTrue(true);
}
public function getOrgProfileImages() : array {
//var_dump(self::$_dashboard);
$members = self::$_dashboard->get_members();
$tmp_array = ['2','2'];
return $tmp_array;
}
public static function tearDownAfterClass()
{
self::$_dashboard = null;
}
}
Error:
The data provider specified for Someclass::testFieldValidation is invalid.
Call to a member function get_members() on null
Please help to mitigate this issue.
Note: since I don't have the source of your Dashboard class, I'm using a random number in the examples below instead
Providers are invoked before any tests are run (and before any hooks, including beforeClass have a chance to run). By far the easiest way to achieve what you're after is to populate that static property on the class load:
use PHPUnit\Framework\TestCase;
/** #runTestsInSeparateProcesses enabled */
class SomeTest extends TestCase
{
public static $_rand = null;
public function provider()
{
$rand = self::$_rand;
var_dump(__METHOD__, getmypid(), 'provided rand', $rand);
return ['rand' => [$rand]];
}
/** #dataProvider provider */
public function testSomething($rand)
{
$this->expectNotToPerformAssertions();
var_dump(__METHOD__, getmypid(), 'tested with', $rand);
}
/** #dataProvider provider */
public function testSomethingElse($rand)
{
$this->expectNotToPerformAssertions();
var_dump(__METHOD__, getmypid(), 'tested with', $rand);
}
}
// this runs before anything happens to the test case class
// even before providers are invoked
SomeTest::$_rand = rand();
Or you could instantiate you dashboard in the provider itself, on the first call:
public function provider()
{
// Instantiate once
if (null === self::$_rand) {
self::$_rand = rand();
}
$rand = self::$_rand;
var_dump(__METHOD__, getmypid(), 'provided rand', $rand);
return ['rand' => [$rand]];
}
#dirk-scholten is right. You SHOULD be creating a new object for each test. It's a GOOD testing practice. Frankly it looks more like you are testing the data and not testing the code, which is fine I guess, it's just not the typical use of PHPUnit. Based on the assumption that you want to make sure every user in the database has a thumbnail image (just guessing), I would go with the following:
<?php
class DashboardDataTest extends PHPUnit\Framework\TestCase {
private $dashboard;
public function setUp() {
$this->dashboard = new Dashboard();
}
/**
* Test Org Thumb Image Existence
* param org profile image : array
*
* #dataProvider getOrgProfileImages
*
* #param int $user_id
*/
public function testThumbnailImageExists(int $user_id){
$thumbnail = $this->dashboard->get_member_thumbnail($user_id);
$this->assertNotNull($thumbnail);
}
public function geOrgUserIDs() : array {
$dashboard = new Dashboard();
// Something that is slow
$user_ids = $dashboard->get_all_the_member_user_ids();
$data = [];
foreach($user_ids as $user_id){
$data[] = [$user_id];
}
return $data;
}
}
Each data provider will get called once and only once before the tests. You do not need a static data fixture on the class because phpunit handles the data fixture for you when you use data providers.

Using $this when not in object context

maybe it is to early in the morning or I'm totally blind, but why to I get a 'Fatal error: Using $this when not in object context' in the following code. There is nothing static in there.
The class:
<?php
class Property
{
/**
* #var string[]
*/
private $values;
public function __contruct($file)
{
$this->values = parse_ini_file($file, false);
}
/**
* #return string
*/
public function get($key, $default = null)
{
if (key_exists($key, $this->values)) { //<-- error
return $this->values[$key];
}
return $default;
}
}
The test:
<?php
class PropertyTest extends Test
{
public function testGet()
{
$prop = new Property($this->getResource('test.properties'));
$this->assertEquals('foo', $prop->get('test.entry', 'xyz'));
$this->assertEquals('bar', $prop->get('test.entry2', 'xyz'));
$this->assertEquals('xyz', $prop->get('test.entry3', 'xyz'));
$this->assertEquals(null, $prop->get('test.entry3'));
}
}
Edit
The error comments indicating the trace. The error occures while running the PropertyTest->testGet() on the the first $prop->get() caused by the first line of the Property->get() method.
Solution
Beside the typo xdazz found, and the deprecation Phil pointed at, user985935 was right. :)
To make it short, my class loader used the static get and the phpUnit error mislead my investigations and my information I offer you for finding my problem. Sorry.
There is a typo in your code.
public function __contruct($file)
which should be
public function __construct($file)
'Fatal error: Using $this when not in object context'
The $this keyword points to methods that are inside an object only you can't use $this outside an object I think this is what causing your problem

Passing __call() parameters by reference fails. Any work around?

I have written a fairly simple lazy loading proxy class, which I have documented in the past over at http://blog.simonholywell.com/post/2072272471/logging-global-php-objects-lazy-loading-proxy
Now as I convert another project to work with it I have been tripped up by proxying a method, which has one of its parameters passed to it by reference. When this goes through the __call method of my proxy class I get:
Fatal error: Method LazyLoader::__call() cannot take arguments by reference in /home/simon/file/name.php
Any clever ideas of how this might be solved or worked around. Preferably without refactoring the code that requires the pass by reference if possible.
The lazy loading proxy class looks like this, but the description in my blog post explains the purpose better:
<?php
/**
* #author Simon Holywell <treffynnon#php.net>
*/
class LazyLoadingProxy {
/**
* Where the instance of the actual class is stored.
* #var $instance object
*/
private $instance = null;
/**
* The name of the class to load
* #var $class_name string
*/
private $class_name = null;
/**
* The path to the class to load
* #var $class_path string
*/
private $class_path = null;
/**
* Set the name of the class this LazyLoader should proxy
* at the time of instantiation
* #param $class_name string
*/
public function __construct($class_name, $class_path = null) {
$this->setClassName($class_name);
$this->setClassPath($class_path);
}
public function setClassName($class_name) {
if(null !== $class_name) {
$this->class_name = $class_name;
}
}
public function getClassName() {
return $this->class_name;
}
public function setClassPath($class_path) {
if(null !== $class_path) {
$this->class_path = $class_path;
}
}
public function getClassPath() {
return $this->class_path;
}
/**
* Get the instance of the class this LazyLoader is proxying.
* If the instance does not already exist then it is initialised.
* #return object An instance of the class this LazyLoader is proxying
*/
public function getInstance() {
if(null === $this->instance) {
$this->instance = $this->initInstance();
}
return $this->instance;
}
/**
* Load an instance of the class that is being proxied.
* #return object An instance of the class this LazyLoader is proxying
*/
private function initInstance() {
Logger::log('Loaded: ' . $class_name);
require_once($this->class_path);
$class_name = $this->class_name;
return new $class_name();
}
/**
* Magic Method to call functions on the class that is being proxied.
* #return mixed Whatever the requested method would normally return
*/
public function __call($name, &$arguments) {
$instance = $this->getInstance();
Logger::log('Called: ' . $this->class_name . '->' . $name . '(' . print_r($arguments, true) . ');');
return call_user_func_array(
array($instance, $name),
$arguments
);
}
/**
* These are the standard PHP Magic Methods to access
* the class properties of the class that is being proxied.
*/
public function __get($name) {
Logger::log('Getting property: ' . $this->class_name . '->' . $name);
return $this->getInstance()->$name;
}
public function __set($name, $value) {
Logger::log('Setting property: ' . $this->class_name . '->' . $name);
$this->getInstance()->$name = $value;
}
public function __isset($name) {
Logger::log('Checking isset for property: ' . $this->class_name . '->' . $name);
return isset($this->getInstance()->$name);
}
public function __unset($name) {
Logger::log('Unsetting property: ' . $this->class_name . '->' . $name);
unset($this->getInstance()->$name);
}
}
Any help greatly appreciated.
The short answer is to not pass by reference. In 99.9% of cases, you don't need it. And in those other 0.1% you can work around the lack of references anyway. Remember, objects are passed by object-reference anyway so you don't need to use variable references for them.
Now, as far as a workaround, I'd personally hardcode that into an adapter. So extend your proxy for that particular class, and include a wrapper for that particular method. Then instantiate that new extended class instead of the core proxy for that class. Is it dirty? Absolutely. But it's your only workaround without refactoring the original class to not take the argument by reference, or refactoring the caller to prevent passing by reference (which is deprecated anyway).
Here is a trick for you, to pass variables by references via __call magic method:
I don't now how long will this works or in witch php versions.
I tested on php 5.3.2
Fitst you cannot pass $arguments variable by $reference in __call function definition. Because php falls with error.
So first:
Here is a code what does not do, what you want with referenced arguments, but nearly good ;)
class A { public $x = array(); }
class Teszt{
private function addElement( &$list ){
$list->x[] = 'new element';
return count($list->x);
}
public function __call($name,$arguments){
if (!preg_match('#^add([0-9]+)Element$#', $name, $matches) || $matches[1]<1){
trigger_error ("Function is not exists teszt::$name", E_USER_ERROR);
}
$ret = null;
for($i=0;$i<$matches[1];$i++){
$ret = call_user_func_array(array($this,'addElement'), $arguments);
}
return $ret;
}
}
$a = new A();
$a->x = array('old element','old element');
$t = new Teszt();
$cnt = $t->add5Element($a);
var_dump($a);
var_dump($cnt);
OUTPUT:
PHP Warning: Parameter 1 to Teszt::addElement() expected to be a reference, value given in /home/gkovacs/callMagicWithReference.php on line 19
PHP Stack trace:
PHP 1. {main}() /home/gkovacs/callMagicWithReference.php:0
PHP 2. Teszt->add2Element() /home/gkovacs/callMagicWithReference.php:27
PHP 3. Teszt->__call() /home/gkovacs/callMagicWithReference.php:0
PHP 4. call_user_func_array() /home/gkovacs/callMagicWithReference.php:19
PHP Warning: Parameter 1 to Teszt::addElement() expected to be a reference, value given in /home/gkovacs/callMagicWithReference.php on line 19
PHP Stack trace:
PHP 1. {main}() /home/gkovacs/callMagicWithReference.php:0
PHP 2. Teszt->add2Element() /home/gkovacs/callMagicWithReference.php:27
PHP 3. Teszt->__call() /home/gkovacs/callMagicWithReference.php:0
PHP 4. call_user_func_array() /home/gkovacs/callMagicWithReference.php:19
object(A)#1 (1) {
["x"]=>
array(2) {
[0]=>
string(11) "old element"
[1]=>
string(11) "old element"
}
}
NULL
ohhh :(((
After a litle 'HACK':
class A { public $x = array(); }
class Teszt{
private function addElement( &$list ){
$list->x[] = 'new element';
return count($list->x);
}
public function __call($name,$arguments){
if (!preg_match('#^add([0-9]+)Element$#', $name, $matches) || $matches[1]<1){
trigger_error ("Function is not exists teszt::$name", E_USER_ERROR);
}
$ret = null;
//Look at my hand, because i will cheat
foreach($arguments as $k=>&$v){ }
//end of cheat
for($i=0;$i<$matches[1];$i++){
$ret = call_user_func_array(array($this,'addElement'), $arguments);
}
return $ret;
}
}
$a = new A();
$a->x = array('old element','old element');
$t = new Teszt();
$cnt = $t->add5Element($a);
var_dump($a);
var_dump($cnt);
Output:
object(A)#1 (1) {
["x"]=>
array(4) {
[0]=>
string(11) "old element"
[1]=>
string(11) "old element"
[2]=>
string(11) "new element"
[3]=>
string(11) "new element"
}
}
int(4)
As we wanted. This works only with objects, but not with array-s.
There is a way with array-s to call-time-pass-by-reference ...
like this: (and of corse you can use this way with objects too)
$cnt = $t->add5Element(&$a);
In this case php generate notices ...
The easiest way to redefine the function if it is possible.
in my code , : private functionaddElement($list) , don't define as reference in parameter list. And as you read in previous message , it will works beacause objects are passed by reference automatically
But sometimes , you can not redefine functions because of implemented interfaces or other reasons ...
Its can. So is hungry.
<?php
class MyClass(){
public function __call($name, $params)
{
var_dump($params);
$params[0][0] = '222';
}
}
$obj = new MyClass();
$info = 3;
var_dump($info);
$obj->setter([&$info]);
var_dump($info);

Categories