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);
Related
What I want to ask is,
let's say I have a class Info and there's a getter in the info called getABC()
In a controller I assigned something like
$info = new Info();
$variable['info'] =$info;
and $variable is being passed into the view.
In the view, am I able to use something like $variable['info']->getABC() ?
I know I can just test it out myself, and failed saying something like it did not exist and $variable['info'] does show something though.
I just want to make sure that $variable['info']->getABC() is suppose to NOT work or it should but I am just doing something wrong that's why I couldn't get what's needed.
actual code below........
Class
class CreditCardPayment{
private $_card_type = '';
private $_card_number = '';
private $_card_number_last_4 = '';
public function setCardType($v)
{
$this->_card_type = $v;
return $this;
}
public function setCardNumber($v)
{
$this->_card_number = $v;
return $this;
}
public function setCardNumberLast4($v) {
$lastFourDigits = substr($v, -4);
$output = 'xxxx-xxxx-xxxx-' . $lastFourDigits;
$this->_card_number_last_4 = $output;
return $this;
}
public function getCardType() {
return $this->_card_type;
}
public function getCardNumber() {
return $this->_card_number;
}
public function getCardNumberLast4() {
return $this->_card_number_last_4;
}
}
and in Controller let's say when it's successful....it'll be something like this where $creditCardPayment = new CreditCardPayment and I tried var_dump($creditCardPayment) that definitely info is all filled and of course those are private variables so I had to use the getter retrieve them.
Controller
$ordermess['creditCardPaymentInfo'] = $creditCardPayment;
\Yii::$app->session->set('ordermess', $ordermess);
$this->redirect('/pay/completed');
then in my view...I did this as testing
<?php
echo '<pre>';
echo ($ordermess['creditCardPaymentInfo']->getCardNumberLast4());
echo '</pre>';
die;
?>
then when I load the page I would get error.
Call to a member function getCardNumberLast4() on a non-object
Yes. It is supposed to work. If there is sanitization code in the function assigning variables to the view, it could be converting the object to an array.
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;
}
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'];
This thread didn't helped me.
If I use
$class_vars = get_class_vars(get_class($this));
foreach ($class_vars as $name => $value) {
echo "$name : $value\n";
}
I get
attrib1_name : attrib2_name : attrib3_name
There are no values. Also a private attribute is shown, which I don't want.
If I use
echo "<pre>";
print_r(get_object_vars($this));
echo "</pre>";
I get
Array
(
[atrrib1_name] => attrib1_value
[attrib2_name] => attrib2_value
)
Here again I have a private attribute and all sub attributes. But this time I have the values. How can I constrain this to one level?
Isn't there a possibility to show all public attributes with their values of an object?
You are seeing non-public properties because get_class_vars works according to current scope. Since you are using $this your code is inside the class, so the non-public properties are accessible from the current scope. The same goes for get_object_vars which is probably a better choice here.
In any case, a good solution would be to move the code that retrieves the property values out of the class.
If you do not want to create a free function for that (why? seriously, reconsider!), you can use a trick that involves an anonymous function:
$getter = function($obj) { return get_object_vars($obj); };
$class_vars = $getter($this);
See it in action.
Update: Since you are in PHP < 5.3.0, you can use this equivalent code:
$getter = create_function('$obj', 'return get_object_vars($obj);');
$class_vars = $getter($this);
You can do this easily with php Reflection api
Extending Mr.Coder's answer, here is a snippet to fetch the public attributes of the object (name and value) as an array
public function getPublicProperties()
{
$results = [];
$reflectionObject = (new ReflectionObject($this));
$properties = $reflectionObject->getProperties(ReflectionProperty::IS_PUBLIC);
foreach ($properties as $property) {
$results[$property->getName()] = $property->getValue($this);
}
return $results;
}
Use get_object_vars.
see: http://dk.php.net/manual/en/function.get-object-vars.php
I Fully recognize what you are trying to achieve so why not have something external like this to help out... (pasted from PHPFiddle)
<?php
final class utils {
public static function getProperties(& $what) {
return get_object_vars($what);
}
}
class ball {
var $name;
private $x, $y;
function __construct($name,$x,$y) {
}
function publicPropsToArray() {
return utils::getProperties($this);
}
function allPropsToArray() {
return get_object_vars($this);
}
}
$ball1 = new ball('henry',5,6);
//$ball2 = new ball('henry',3,4);
echo "<pre>";
print_r($ball1->publicPropsToArray());
echo "\r\n\r\n";
print_r($ball1->allPropsToArray());
echo "\r\n\r\n";
?>
This way I can both access all properties of the object or for something such as a database access layer or similarly for a function that send "safe" data to a view or another un-privileged model I can send just the public properties, but have the behaviour defined within the object.
Sure this leads to coupling with a utility class, but to be fair not all couplings are bad, some are nesecarry to achieve an end goal, dont get bogged down by these things
I can't quite understand why the output of this code is '1'.
My guess is that php is not behaving like most other OO languages that I'm used to, in that the arrays that php uses must not be objects. Changing the array that is returned by the class does not change the array within the class. How would I get the class to return an array which I can edit (and has the same address as the one within the class)?
<?php
class Test
{
public $arr;
public function __construct()
{
$this->arr = array();
}
public function addToArr($i)
{
$this->arr[] = $i;
}
public function getArr()
{
return $this->arr;
}
}
$t = new Test();
$data = 5;
$t->addToArr($data);
$tobj_arr = $t->getArr();
unset($tobj_arr[0]);
$tobj_arr_fresh = $t->getArr();
echo count($tobj_arr_fresh);
?>
EDIT: I expected the output to be 0
You have to return the array by reference. That way, php returns a reference to the array, in stead of a copy.
<?php
class Test
{
public $arr;
public function __construct()
{
$this->arr = array();
}
public function addToArr($i)
{
$this->arr[] = $i;
}
public function & getArr() //Returning by reference here
{
return $this->arr;
}
}
$t = new Test();
$data = 5;
$t->addToArr($data);
$tobj_arr = &$t->getArr(); //Reference binding here
unset($tobj_arr[0]);
$tobj_arr_fresh = $t->getArr();
echo count($tobj_arr_fresh);
?>
This returns 0.
From the returning references subpage:
Unlike parameter passing, here you have to use & in both places - to
indicate that you want to return by reference, not a copy, and to
indicate that reference binding, rather than usual assignment, should
be done
Note that although this gets the job done, question is if it is a good practice. By changing class members outside of the class itself, it can become very difficult to track the application.
Because array are passed by "copy on write" by default, getArr() should return by reference:
public function &getArr()
{
return $this->arr;
}
[snip]
$tobj_arr = &$t->getArr();
For arrays that are object, use ArrayObject. Extending ArrayObject is probably better in your case.
When you unset($tobj_arr[0]); you are passing the return value of the function call, and not the actual property of the object.
When you call the function again, you get a fresh copy of the object's property which has yet to be modified since you added 5 to it.
Since the property itself is public, try changing:
unset($tobj_arr[0]);
To: unset($t->arr[0]);
And see if that gives you the result you are looking for.
You are getting "1" because you are asking PHP how many elements are in the array by using count. Remove count and use print_r($tobj_arr_fresh)