?
Solved

Access modifier "public" not having expected results in PHP

Posted on 2014-07-28
18
Medium Priority
?
153 Views
Last Modified: 2014-08-04
Since I'm using "public" in the first class, I would expect that method to be available to a different object in another class, but when trying to call the say_hello() function, i get an error:

Fatal error: Call to undefined method Car::say_hello()

I thought public was supposed to allow anything in that class to be used elsewhere?  Thanks.

<?php

class Person {
	public function say_hello() {
		echo "Hello from inside the class ". get_class($this) .".<br />";
	}
	
	public function hello() {
		$this->say_hello();
	}
}


class Car {
	public $wheels = 4;
}


$ford = new Car;

$ford->say_hello();

?>

Open in new window

0
Comment
Question by:LB1234
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 7
18 Comments
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40224037
Person::say_hello() exists.  Car::say_hello() does not.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40224041
But with that said, you're at the threshold of one of the great concepts in object-oriented programming: Inheritance.  Car and Person can become mutual extensions of one another.  I'll show you an example in a moment.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40224052
Notice line 20!  In this example, an instance of the Car class will have direct access to all of the methods of the Person class, because of the way we used Extends.  There are many reasonable uses for object inheritance (and better examples).  I'll scrape up a better one for you in a moment.

<?php // demo/temp_lb1234.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28485227.html

class Person
{
	public function say_hello()
	{
		echo "Hello from inside the class ". get_class($this) .".<br />";
	}

	public function hello()
	{
		$this->say_hello();
	}
}


class Car extends Person
{
	public $wheels = 4;
}

// CREATE AN INSTANCE OF THE CAR AND CALL THE METHOD DEFINED INSIDE PERSON
$ford = new Car;
$ford->say_hello();

// SHOW THAT THE $ford OBJECT HAS WHEELS
var_dump($ford);

Open in new window

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:LB1234
ID: 40224063
Person::say_hello() exists.  Car::say_hello() does not.

In this bit of code, I thought :: was to denote the use of a constant?  And that methods were called with $variable->method.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40224130
Try this one.  See if the relationship between the Cat and Tiger objects make sense.  Once you grasp that, you can envision how a membership object could be used in a data base.  All of the members would share common qualities (name, address, phone) but some might be basic members and some might be premium members.  Or consider automobiles.  Class Mercedes and Class Audi would both extend Class Car, but each would bring unique features on top of the basic Car paradigm.

<?php // basic_inheritance.php
error_reporting(E_ALL);
echo '<pre>';

// REF: http://php.net/manual/en/language.oop5.inheritance.php

class Feline
{
    // ALL FELINES HAVE CLAWS
    public function claws()
    {
        return "claws";
    }
}

Class Cat Extends Feline
{
    // CATS MEOW
    public function speak()
    {
        return "meow";
    }
}

Class Tiger Extends Feline
{
    // TIGERS ROAR
    public function speak()
    {
        return "ROAR!";
    }
}

// CREATE A NEW CAT AND A NEW TIGER
$tabby = new Cat;
$simba = new Tiger;

// SHOW THAT THEY BOTH HAVE CLAWS
echo PHP_EOL;
echo 'Cat: ';
echo $tabby->claws();
echo PHP_EOL;
echo 'Tiger: ';
echo $simba->claws();

// SHOW THAT THEY HAVE DIFFERENT VOICES
echo PHP_EOL;
echo 'Cat: ';
echo $tabby->speak();
echo PHP_EOL;
echo 'Tiger: ';
echo $simba->speak();

Open in new window

0
 
LVL 111

Assisted Solution

by:Ray Paseur
Ray Paseur earned 2000 total points
ID: 40224153
About the :: and the ->

The :: is the scope resolution operator.  In round terms, it tells PHP where to look for the property or method (what class) when it is being called statically.  Static methods and properties do not need object instantiation to be useful.

The -> is the notation we use to tell PHP where to look for the property or method when it is being called dynamically (for want of a better term).  It's used after object instantiation.

BTW, this is a good note:
http://php.net/manual/en/language.oop5.properties.php#108320
0
 
LVL 1

Author Comment

by:LB1234
ID: 40225103
Thanks Ray!  Taking some time to go through the links you provided so I don't ask questions that might be explained in one of them.  Quite a lot of info there, so I will comment soon.  The examples were great, although did have some questions, but reading links first.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40225566
It's a lot to learn, but the good news is that once you learn OOP you will never think about complex problems the same way again.  They will almost automatically break themselves down into bite-sized pieces!
0
 
LVL 1

Author Comment

by:LB1234
ID: 40234928
Ray, in my book "Beginning PHP 5.3" it reads the following:

"Public properties can be accessed by any code, whether that code is inside or outside the class.  If a property is declared public, it's value can be read or changed from anywhere in your script.

In my original code, I'm still not sure how this statement is being violated.
0
 
LVL 111

Assisted Solution

by:Ray Paseur
Ray Paseur earned 2000 total points
ID: 40234965
From the original code snippet, with comments.  Does this help?

<?php

class Person {                        // "Person" CLASS DEFINITION STARTS HERE
    public function say_hello() {
        echo "Hello from inside the class ". get_class($this) .".<br />";
    }
    
    public function hello() {
        $this->say_hello();
    }
}                                     // "Person" CLASS DEFINITION ENDS HERE


class Car {                           // "Car CLASS DEFINITION STARTS HERE
    public $wheels = 4;
}                                     // "Car CLASS DEFINITION ENDS HERE


$ford = new Car;                      // CREATES AN INSTANCE OF "Car"

$ford->say_hello();                   // THE "say_hello()" METHOD IS IN "Person" AND IS NOT IN "Car"

Open in new window

0
 
LVL 1

Author Comment

by:LB1234
ID: 40234976
So the definition is misleading.  Public stuff can be used by anything in the class, not anything in the entire script?
0
 
LVL 111

Accepted Solution

by:
Ray Paseur earned 2000 total points
ID: 40235121
I think the misunderstanding may be about scope resolution, which is one of the most important tenets of OOP.  Class Person has two public methods.  They are public because the definition says so.  They are methods of the Person class because they are defined between the opening and closing curly braces of the Person class definition.  These methods can be called from anywhere in the script because they are public.  They can be called in one of two ways.

They can be called statically by writing Person::Say_hello(), since this will tell PHP to look for the say_hello() method in the Person class definition.  This will probably fail because of the use of $this, but it would be syntactically correct for a static function call.

They can be called dynamically by creating an object instance of the Person class (let's call it $p) and then writing $p->say_Hello().

You might have several say_hello() methods in a program and it's perfectly OK so long as they belong to different classes.  But PHP has to be told which class to use in order to find the say_hello() method.  Without a scope resolution operator, PHP will assume that say_hello() is a function in the main scope of the script, and will not find the say_hello() method in the classes or objects.  For obvious reasons only one say_hello() method is permitted in the main scope of the script.  More than one would be ambiguous and computers hate ambiguity.  

In the OOP5 inheritance model, when a class extends another class, it inherits all of the parent class methods and can override any/all of the methods.
0
 
LVL 1

Author Closing Comment

by:LB1234
ID: 40238712
Thanks again Ray, got it now!
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40238873
Great!  Thanks for the points -- it's a really good question.
0
 
LVL 1

Author Comment

by:LB1234
ID: 40239574
This makes sense or doesn't depending on how one interprets the term "inside the class."  PHP means LITERALLY within the confines of the brackets themselves, NOT inside as in, within the logical grouping of a class.  And that's what was throwing me off.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40239660
In PHP the only "logical grouping" of a class is the set of curly brackets.  Same thing for a function:

function thing()
{
    /* THIS IS INSIDE THE "Thing() FUNCTION */
}
/* THIS IS OUTSDE THE FUNCTION, AND HAS A DIFFERENT SCOPE */
0
 
LVL 1

Author Comment

by:LB1234
ID: 40239667
Clears as day now thanks to your explanations.  I don't think my book was explicit enough about what it meant by "inside a class."
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 40239810
Remember that when you write your book!

:-)

Ray
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

These days socially coordinated efforts have turned into a critical requirement for enterprises.
There are times when I have encountered the need to decompress a response from a PHP request. This is how it's done, but you must have control of the request and you can set the Accept-Encoding header.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question