Jump to content
Larry Ullman's Book Forums

Recommended Posts

Larry,

 

At the end of chapter 5 you mention in a tip that static methods are almost always public because they can't be called through an object.

 

Substituting $dog->getCount() for Pet::getCount() in line 74 of script 5.6 (page 179) produces identical output. Can you please expound?

 

Also... Dog::getCount() prints the same results as Pet::getCount() when getCount() is declared public static; however, Dog::getCount() does not print properly when it is declared protected static even though class Dog extends Pet{ }?

 

Can you please explain that as well?

 

Thank you,

Hacker

Link to comment
Share on other sites

This is due to error reporting settings. You'll get an E_NOTICE warining you about "Strict standards" and calling a static method in an object context. This blog post might clarify http://www.lornajane.net/posts/2010/declaring-static-methods-in-php

 

For the second question, you need to read the part about visibility modifiers one more time. A protected method/property is only callable within the declaring class and classes that inherits from it internally. You cannot call a protected method via application code no matter why.

 

To clarify, you wouldn't be able to use Pet::getCount(); when the modifier is protected neither.

<?php

class Pet
{
    protected $name;
    private static $_count = 0;

    function __construct( $pet_name )
    {
        $this->name = $pet_name;
        self::$_count++;
    }

    // Destructor decrements the counter:
    function __destruct()
    {
        self::$_count--;
    }

    // Static method for returning the counter:
    protected static function getCount()
    {
        return self::$_count;
    }

}

// End of Pet class.

class Dog extends Pet
{
    public static function count()
    {
        return parent::getCount(); // Or Dog::getCount(); Both works.
    }
}

// Create a dog:
$dog = new Dog('Old Yeller');
echo Dog::count();
// echo Pet::count();           Not allowed. Pet does not have count()!
// echo Pet::getCount();        Not allowed, protected method!
// echo Dog::getCount();        Not allowed, protected method!
Link to comment
Share on other sites

 

This is due to error reporting settings. You'll get an E_NOTICE warining you about "Strict standards" and calling a static method in an object context.

 

I'm just going to respond to your first comment for now and I'll study your example when I have more time; however, I think I found the answer to my second question in the "Access Control" section starting on page 165... thank you.

 

Now back to the first point... I get no warning of any kind... at least while running PHP 5.4 (yes, I have display_errors turned ON).  Like I said above, I get the same output whether I use $dog->getCount() or Pet::getCount().

 

Dog::getCount() also works, but that's no surprise to me.

 

Thanks,

Hacker

Link to comment
Share on other sites

Antonio,

 

According to phpinfo.php, my error_reporting is set to 22527; however, the only occurrence of error_reporting in my php.ini file that is not commented out reads:

 

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

 

Thanks,

Hacker

Link to comment
Share on other sites

Yes? Change that to -1 and you'll get the error I wrote about.

 

Antonio,

 

Got any other ideas?  My error_reporting is now set to -1 (according to phpinfo) and I'm still getting the following output (while getCount is declared public static) without error messages or warnings:

 

After creating a dog, I now have 1 pets.

After creating a dog, I now have 1 pets.

After creating a dog, I now have 1 pets.

After creating a cat, I now have 2 pets.

After creating a ferret, I now have 3 pets.

 

While using the following code:

 

$dog = new Dog('Old Yeller');

echo '<p>After creating a dog, I now have '.$dog->getCount().' pets.</p>';

echo '<p>After creating a dog, I now have '.Pet::getCount().' pets.</p>';

echo '<p>After creating a dog, I now have '.Dog::getCount().' pets.</p>';

    

$cat = new Cat('Bucky');

echo '<p>After creating a cat, I now have '.Pet::getCount().' pets.</p>';

 

$ferret = new Ferret('Fungo');

echo '<p>After creating a ferret, I now have '.Pet::getCount().' pets.</p>'; 

 

I'm toward the end of chapter six now and trying to make my way into the example contained in chapter nine. If I don't make it back here for a while... thank you in advance.

 

Hacker 

Link to comment
Share on other sites

I'm telling you. The error is obviously related to error reporting settings. I even tried it in practice to confirm the behavior. You CAN call a static method by object syntax in PHP, but it WILL raise a warning. You SHOULD still see that output, but PHP will warn you about the usage when you report in accordance to strict standards. The problem might be an old PHP version where those strict standards are not yet applied, but that's merely a guess.

Link to comment
Share on other sites

The error is obviously related to error reporting settings.

 

OK, so what else do I need to do in my php.ini file in order to see some warning action?  I realize this issue isn't directly related to Larry's book so if you want to refer me to another source, go right ahead.

 

I'm running PHP version 5.4.24 and Apache 2.2.26 on MacOSX (v10.9).

 

Hacker

 

P.S. BTW and with all due respect, while you keep beating the error reporting drum, that doesn't really reconcile the fact that Larry wrote in his book, "static methods are almost always public because they can't be called through an object."  Granted, I'm no Zend Certified engineer but when someone says they can't be called through an object, I expect to see the script terminate with fatal errors.

 

Is Larry on vacation?

Link to comment
Share on other sites

My best guess is that you're seeing this because of a change in PHP version, as Antonio suggested. But it kind of sounds like you're fixating on a minor point. The static restriction is theoretical, used to enforce proper design, which is why PHP should send up a warning. The benefit or main reason to use static is to make a method or class be globally accessible and shared.

Link to comment
Share on other sites

Larry,

 

I was nosing around in the PHP manual and suggest you read this:

 

http://us3.php.net/manual/en/language.oop5.static.php

 

Near the top of the page it says:

 

"Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can)."

 

Regards,

Hacker

Link to comment
Share on other sites

That is mostly phrasing. This is a syntax and design oriented debate more than an anything. You can't write code like that without experts raising their brows at you. You can't write code like that without breaking object oriented syntax. You can't write code like that without raising warnings.

 

Can you write code like that in practice? Yeah, but then you don't get the point... You might've picked upon some of my irritation explaining in previous post, and the proper answer is actually just that. You can write code like that, but then you really can't. - Not if you want to be a proper programmer and follow the rules and abstractions of object-oriented design. Code is just expression of logic, so your grammar would be wrong.

 

Nothing in your quote nor your link contradicts anything said by me or Larry in this thread, btw. I agree with Larry that you focus too much on the lack of a PHP warning. It's still wrong according to syntax, or grammar if you like that analogy better.

  • Upvote 2
Link to comment
Share on other sites

It's still wrong according to syntax...

 

What's still wrong according to syntax? Are you refering to my $dog->getCount() in my opening post? What part of "...A property declared as static can not be accessed with an instantiated class object (though a static method can)" don't you understand? If you're not satisfied with the PHP manual, I don't know what to tell ya.

 

Actually, I don't give a hoot... the PHP manual cleared up my confusion and I'm happy.

 

Good night,

Hacker

Link to comment
Share on other sites

There are design and syntax reasons for not allowing it, as it doesn't make sense logically. It grays out important destinations between objects and classes. I don't think the change is a good one, but that is beside the point.

 

As long as you fully understand the difference between objects and classes, that's really what is most important. I'm sorry if I pushed any buttons of yours along the way. It turns out PHP did change along the way, and while I don't agree with it, you where right. I try never to be to proud to admit when I'm wrong.

Link to comment
Share on other sites

It surprised me, but PHP no longer generates an E_STRICT when you call a static method through an instantiated object. (Like it used to do, and is pretty much the center of debate) I really believe it still should, but it turns out I was wrong. I don't agree with the change, but it is what it is. I still stand by all of my opinions, but I like to admit it when I'm wrong.

 

You can "legally syntactically" call a static method though an instantiated object, but you still shouldn't as it's bad grammar and wrongly reflects the logic you are trying to communicate. I think this is a PHP flaw that will only help confuse the difference about procedural code (as static code is) and object-oriented programming.

Link to comment
Share on other sites

Okay, I understand. I just wasn't sure what you were referring to when you said that "PHP changed along the way".

Thanks.

 

Also, yes, I agree that PHP should still throw an error.

I'm not sure how they arrived at the decision to be less stringent.

 

Also, hacker, while I'm not on this forum to take sides, Antonio is an excellent OOP PHP programmer, and I agree with everything he has said in this thread, so while it might hurt your pride a bit now, I highly recommend following his advice and learning from it.

  • Upvote 1
Link to comment
Share on other sites

  • 4 months later...
 Share

×
×
  • Create New...