How to create a dynamic property in a class? - php

I need to create a property called "aip-aup" in a class but I can't get it to work.
First tried to put it up with the property definitions. Unfortunately bracketed property-definitions are not allowed.
This fails (in the __construct()):
$this->${'aip-aup'} = array();
Gives error "Undefined variable 'aip-aup'".
This as well (in the __set method):
$this->${'aip-aup'}[$property] = $value;
Also tried creating a custom helper method, but does absolutely nothing:
$this->createProperty('aip-aup', array());
Any help here?
The property has to be public so should be doable?

If you need doing something like this, then you are doing something wrong, and it would be wise to change your idea, than trying to hack PHP.
But if you have to, you can try this:
class Test {
public $variable = array('foo'=>'bar');
public function __get($name){
if ($name == 'aip-aup'){
return $this->variable;
}
}
}
$test = new Test();
$func = 'aip-aup';
$yourArray = $test->$func;
echo $yourArray['foo'];

Related

PHP - Call object methods dynamically via variables

I am trying to unit-test some of my code and it would be easier to just call my setters dynamically based on some variables. Unfortunately my approach does not work as expected and I couldn't find more information regarding on how to do that.
I have one variable which always is a string. It is used as property name and together with the "set" keyword it should result in "setSomething" or "setSomethingElse".
I already tried
$obj->set{$property}($value);
// or
$obj->set$property($value);
But those do not seem to work.
Maybe someone of you pro's know the right approach ;)!
You need to make the entire method name a variable, or enclose the whole name in {} e.g.
class test {
public $Something;
public $SomethingElse;
function setSomething($value) {
$this->Something = $value;
}
function setSomethingElse($value) {
$this->SomethingElse = $value;
}
}
$property = "Something";
$t = new test;
$setter = "set$property";
$t->$setter(4);
echo $t->Something;
$property = "SomethingElse";
$t->{"set$property"}(8);
echo $t->SomethingElse;
Output
4
8
Demo on 3v4l.org

Set an array from class and get him outside a class

I would create an array with ID posts from inside a function, and get him outside the class.
My code:
<?php
class cat_widget extends WP_Widget {
private $newHomePost = array();
function widget($args, $instance){
//...
foreach($img_ids as $img_id) {
if (is_numeric($img_id)) {
$this->setNewHomePost($newsCounter,$post->ID);
$newsCounter++;
//...
}
}
}
function setNewHomePost($num, $value){
$newHomePost[$num] = $value;
}
function getNewHomePost(){
return "ID: ".$this->newHomePost[0];
}
}
$testA = new cat_widget();
echo $testA->getNewHomePost();
?>
I receive on screen this resuld:
ID:
(without the id)
But if I insert inside setNewHomePost() an echo for the array, I'll obtain correctly the array but inside and not outside class.
function setNewHomePost($num, $value){
$newHomePost[$num] = $valore;
echo $newHomePost[0];
}
So seem that the array works fine inside the "function widget", but doesn't works outside it.
Can someone help me, please?
function setNewHomePost($num, $value){
$newHomePost[$num] = $value;
}
This creates a local variable named $newHomePost, setting a value at an index and returning. Once it returns, the local variable disappears. From the linked manual page:
Any variable used inside a function is by default limited to the local function scope.
You want to set the class member property newHomePost instead:
function setNewHomePost($num, $value) {
$this->newHomePost[$num] = $value;
}
Update
This is how you currently have the get method defined:
function getNewHomePost() {
return "ID: " . $this->newHomePost[0];
}
I suspect you're still fiddling with this and trying to get it to work. If you really want to just only ever return the 0'th index, try something like this instead:
function getNewHomePost() {
return isset($this->newHomePost[0]) ? $this->newHomePost[0] : null;
}
When building a class remember that you cannot make any assumptions about what order your public methods can be called from another object or calling code (even if the calling code itself exists inside of the class. The methods are public, meaning anything can call them). The code above assumes nothing in that you do not have to call addNewHomePost prior to getNewHomePost. I imagine if you look in your logs you may see a few Notice: Undefined index.. type errors.
Also be sure to check on the calling side:
$myClass = new cat_widget;
$myClass->setNewHomePost(0, 'my new home post!');
$homePost = $myClass->getNewHomePost();
echo $homePost ? $homePost : 'None';
I think a better getter method would probably look like this:
function getNewHomePost($i) {
return isset($this->newHomePost[$i]) ? $this->newHomePost[$i] : null;
}

how to call Joomla component method by variable?

$model = JModelLegacy::getInstance('NameOfModel', $prefix = 'my_componentModel', $config = array());
Normally, I would call the models method like this:
$this->items = $model->my_method();
In my case, I need to call the method by variable, because it is dynamic:
$this->items = $model->$variable; ...but this won't work.
$this->items = $model->{$variable}; ...this also won't work.
Does anybody know how to solve this?
If your code sample is right, the most likely answer is that you mean to call a method whose name is $variable, but you've forgotten the () at the end. i.e. your calling line should read:
$this->items = $model->$variable();
If, that's not a typo and you did mean to call a property of the class, it's likely that the contents of $variable don't have a matching property/method in $model.
When using variable properpty or method names you will better off wrapping your calls in a simple check the existence of the property or method, to catch the problem before hand. e.g.
// Check $model has a method $variable
if (method_exists($model, $variable)
{
$this->items = $model->$variable();
}
else
{
... raise a error/warning message here ...
}
// Check $model has a property $variable
if (property_exists($model, $variable)
{
$this->items = $model->$variable;
}
else
{
... raise a error/warning message here ...
}

Is it possible to pass a variable stored in an array by reference in PHP?

If I want myFunction to take $myVariable and assign to it an instance of SomeClass, I know I can do this:
class SomeClass { }
function myFunction(&$myVariable) {
$myVariable = new SomeClass();
}
myFunction($myVariable);
var_dump($myVariable);
However, I would like to be able to have myFunction operate like this:
class SomeClass { }
function myFunction($args = array()) {
if(isset($args['something'])) {
$$args['something'] = new SomeClass();
}
}
myFunction(array(
'something' => $myVariable
));
var_dump($myVariable);
Is there any way to achieve this?
it's an ugly hack but could work:
global $$args['something'];
$$args['something'] = new SomeClass();
But you should never introduce such side effects.
You can only pass variables by reference, so
myFunction(array())
will not work in either case.
Im not sure what your doing, but lets say
$myVariable = 'Mary';
$array['something'] = $myVariable;
Then
$$array['something'] === $Mary
Which doesnt exist.
I havent tested it, but I dont think that will work the way you want it to, even with global variables.

PHP string to object name

Ok I have a string...
$a_string = "Product";
and I want to use this string in a call to a object like this:
$this->$a_string->some_function();
How the dickens do I dynamically call that object?
(don't think Im on php 5 mind)
So you the code you want to use would be:
$a_string = "Product";
$this->$a_string->some_function();
This code implies a few things. A class called Product with the method some_function(). $this has special meaning, and is only valid inside a class definition. So another class would have a member of Product class.
So to make your code legal, here's the code.
class Product {
public function some_function() {
print "I just printed Product->some_function()!";
}
}
class AnotherClass {
public $Product;
function __construct() {
$this->Product = new Product();
}
public function callSomeCode() {
// Here's your code!
$a_string = "Product";
$this->$a_string->some_function();
}
}
Then you can call it with this:
$MyInstanceOfAnotherClass = new AnotherClass();
$MyInstanceOfAnotherClass->callSomeCode();
I seem to have read this question differently from everyone else who's responded, but are you trying to use variable variables?
In the code you've shown, it looks like you're trying to call a function from string itself. My guess is that you want to call a function from a class with the same name as that string, in this case "Product."
This is what that would look like:
$this->Product->some_function();
It seems you might instead be looking for something like this:
$Product = new Product();
$Product->some_function();
EDIT: You need to be running PHP5 in order to do any method chaining. After that, what you have is perfectly legal.
Let's see if I got your intentions correctly...
$some_obj=$this->$a_string;
$some_obj->some_function();
So you've got an object, and one of it's properties (called "Product") is another object which has a method called some_function().
This works for me (in PHP5.3):
<?PHP
class Foo {
var $bar;
}
class Bar {
function some_func(){
echo "hello!\n";
}
}
$f = new Foo();
$f->bar = new Bar();
$str = 'bar';
$f->$str->some_func(); //echos "hello!"
I don't have PHP4 around, but if it doesn't work there, you might need to use call_user_func() (or call_user_func_array() if you need to pass arguments to some_function()

Categories