$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 ...
}
Related
Is this possible Im trying to do this with the extract() function since Im unable to get the method arguments in advance
class Test{
public function getData($id){
//use $id here
}
}
$class = 'Test'; //this is determined dymanically
$method = 'getData'; //this is also determined dynamically
$arguments = ['id'=>'1234'];
$test = new $class();
$test->{$method}(extract($arguments));
//this generates a warning Missing argument 1 for Test::getData(),
called
How can this be implemented?
EDIT
It appears I've simplified it too much, the code is intended to be the main deployment mechanism in a mini-framework Im developing so the method - getData is determined dynamically and therefore I cant know the arguments for each method in advance.
Thanks
extract is for assigning to variables. For each element of the associative array, it will assign to a variable in the current scope with that name. It returns the number of variables it assigned, not the value of any of the variables.
There's no reason to use extract in your case, just get the element of the array that you want:
$test->getData($arguments['id']);
I'm not sure why you're getting an error about a missing argument. It should pass 1 as the $id argument, since there's one element in the array.
If you don't know which elements the function needs, a better design would be to pass the whole $arguments array to the function, and let it use the parts it wants.
public function getData($args) {
$id = $args['id'];
// Use $id
}
...
$test->getData($arguments);
Just extract your array and pass $id
<?php
class Test{
public function getData($id){
echo $id;
}
}
$arguments = array('id'=>'1234');
extract($arguments);
$test = new Test();
$test->getData($id);
or
$arguments = array('id'=>'1234');
extract($arguments);
$test = new Test();
foreach($arguments as $key=>$value){
$test->getData($$key);
}
Ive found the solution using ReflectionMethod
$reflection = new \ReflectionMethod('Test', 'getData');
$pass = [];
foreach($reflection->getParameters() as $param){
//parse the method to get its arguments and filter through the sent arguments array
if(isset($args[$param->getName()])){
//check if the arguments exists and select them
$pass[] = $args[$param->getName()];
}
else{
$pass[] = $param->getDefaultValue();
}
}
//execute the resolved parameters
return $reflection->invokeArgs(new Test, $pass);
I'm working on a logging class, and I'd like to add a convenience function which would log the arguments of the function from which it is called. A little convoluted, so here's some code:
function MyFunc($arg1, $arg2) {
global $oLog;
$oLog->logArgs();
}
So, I can get the name of the calling function (MyFunc) using debug_backtrace(). I'd be interested in getting the names and values of the arguments, preferably without having to add func_get_args() in the call to logArgs().
I know it's a tall order, but PHP continues to surprise me, so I'm putting it out there, just in case.
Thanks.
You can do this with reflection:
function logger()
{
$bt = debug_backtrace();
$previous = $bt[1];
if(empty($previous['class'])) {
$fn = new ReflectionFunction($previous['function']);
} else {
$class = new ReflectionClass($previous['class']);
$fn = $class->getMethod($previous['function']);
}
$parameters = $fn->getParameters();
//Get a parameter name with $parameters[$paramNum]->getName()
//Get the value from $previous['args'][$paramNum]
}
This particular implementation won't work with closures, but it will work with both global functions and class methods.
I need a way to have breadcrumbs that are not generated from the URL.
My thought process is to have a class, "Breadcrumbs" which will work as:
$breadcrumbs = new BreadCrumb('<<')->crumb('www.google.com', 'Google')->crumb('www.youtube.com', 'Youtube');
Which will generate an array, and with each method chain it will push back into the array, resulting in one array which I can then turn into a URL structure.
I have tried the following:
class Breadcrumbs {
public $del;
public $breadcrumbs;
public function __construct($del)
{
$this->breadcrumbs = array();
$this->del = $del;
}
public function crumb($uri, $name)
{
$this->breadcrumbs[] = array($uri => $name);
}
}
This, however, does not provide an accurate result, and get 'unexpected '->'' when trying to do the structure as I plan to do.
Any ideas to where I am going wrong?
To do method chaining, you need to return an object from your method call. Typically you'll want:
return $this; // in function crumb()
The correct syntax to instantiate an object and immediately call a method on it is:
(new BreadCrumb('<<'))->crumb(..)
Without the extra parentheses it's ambiguous to PHP what you want to do.
Aside: you don't need to initialise your array inside the constructor, you can do that while declaring the array:
public $breadcrumbs = array();
Aside: this is pretty inefficient:
.. = array($uri => $name)
You'll have a hard time getting that $uri key back out of the array, which makes your code unnecessarily complicated. You should simply do:
$this->breadcrumbs[$uri] = $name;
Alternatively, if your URIs aren't guaranteed to be unique, use a structure that's easier to work with later:
$this->breadcrumbs[] = array($uri, $name); // $arr[0] is the URI, $arr[1] the name
You need to return $this from crumb to be able to do method chaining.
public function crumb($uri, $name)
{
$this->breadcrumbs[] = array($uri => $name);
return $this;
}
Can someone show, fixed or tell me why i am getting this error
Call to a member function getRating() on a non-object
Here is the function
public function getRating($movieid){
$movieid = mysql_real_escape_string($movieid);
$average = 0;
$e = mysql_query("SELECT AVG(`rating`) as average FROM movie_ratings WHERE movieid='$movieid'") or die(mysql_error());
if (mysql_num_rows($e)>0){
extract(mysql_fetch_array($e));
}
return $average;
}
And This is how i call the function
$movie = $movie->getByPerma($perma,$language);
if (empty($movie)){
$movie = '';
} else {
$movie['rating'] = $movie->getRating($movie['id']);
$tags = $movie->getMovieCategoryDetails($movie['id'],$language);
if (count($tags)){
$smarty->assign("tags",$tags);
} else {
$smarty->assign("tags","");
}
}
Can someone help me as i'm new to php.
$movie->getByPerma($perma,$language);
is returning something that is not an object.
So I would
print_r($movie)
on line 2 and see what I'm getting.
The second wierd thing is in:
$movie['rating'] = $movie->getRating($movie['id']);
On the left side you are using $movie as an array and on the right side you are using it as an object and then again yo sent the parameter you use $movie['id'] as an array.
So:
If you are getting an array, the array cant have functions, the function should be outside a class and will be called like this:
getRating($movie['id'])
istead of
$movie->getRating($movie['id']).
If you are getting an object, and the object implements the function
getRating($movie_id)
then the way to access the properties of the object is:
$movie->rating and $movie->id
I'm asuming that the properties are declared public. This is not the correct way of doing it though... The properties should be private and you should implemente getters and setters for the objects properties like this:
private $rating;
public function get_rating()
{
return $this->rating;
}
In this case to get the rating, use
$movie->get_rating();
And to asign a value to the rating, implement
public function set_rating($r)
{
$this->rating=$r;
}
And asign value like this:
$movie->set_rating($some_rating);
Dunno if I helped or made everything more confusing :S but feel free to ask me questions :)
Unclear what the issue is without seeing the rest of the code, but it seems like you are instantiating $movie for a class at one point and then assigning $movie as an array. That can’t be good since the array $movie assignment will just wipe out the class $movie assignment.
I would recommend renaming the class variable or array. Here is it with the array renamed $movie_array:
$movie_array = $movie->getByPerma($perma,$language);
if (empty($movie_array)){
$movie_array = '';
} else {
$movie_array['rating'] = $movie->getRating($movie_array['id']);
$tags = $movie->getMovieCategoryDetails($movie_array['id'], $language);
if (count($tags)){
$smarty->assign("tags", $tags);
} else {
$smarty->assign("tags","");
}
}
And here it is with the class renamed $movie_class:
$movie = $movie_class->getByPerma($perma,$language);
if (empty($movie)){
$movie = '';
} else {
$movie['rating'] = $movie_class->getRating($movie['id']);
$tags = $movie_class->getMovieCategoryDetails($movie['id'], $language);
if (count($tags)){
$smarty->assign("tags", $tags);
} else {
$smarty->assign("tags","");
}
}
It looks like
$movie = $movie->getByPerma($perma,$language);
is not returning an object, and so then later in the code when you call
$movie['rating'] = $movie->getRating($movie['id']);
you are calling a function on a non-object. check to see what $movie is equal to before this line by using
var_dump($movie);
$movie=['rating'] = $movie->getRating($movie['id']);
Not sure though, Seems like $movie = $movie->getByPerma($perma,$language); is not returning an object. Try to do var_dump($movie);
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'];