SitePoint Sponsor

User Tag List

Results 1 to 22 of 22
  1. #1
    SitePoint Member
    Join Date
    Feb 2008
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question Probing the oop capabilities of PHP

    Hi I am trying to explore the class & object facilities written into PHP.
    I have a new 64bit computer with a quad processor running on a Windows vista Business OS, I have loaded PHP v5.2.14 which may or may not have all of the required configuration file extensions included. I am using IIS.
    I have written two PHP files, one which contains only the class code and another which calls it and displays the value of the class property (one only to begin with for simplicity).

    File product.php
    PHP Code:
    <?php
    class Ch2_Product
    {
      
    // properties defined here
    //  protected $_type = 'Book';

      // methods defined here
    //  public function getProductType()
    //  {
    //    return $this->_type;
    //  }
    //  public function setProductType($type)
    //  {
    //    $this->_type = $type;
    //  }
    }
    File product_test.php
    PHP Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.3.org/1999/xhtml">
    <head>
    <title>Experimenting with visability</title>
    <meta http-equiv="content-type"
       content="text/html; charset=iso-8859-1" />
    </head>
    <body>
    <?php
      
    // include the class file
      
    require_once 'Product.php';
    //  require_once(dirname(__FILE__) . "Product.php");


      // create an instance of the Ch2_Product class
      
    $product = new Ch2_Product();

      
    // display the $_type property
    //  echo $product->_type;

    </body>
    </
    html>
    launching the file called product_test I get a 500 error message (not able to display the page. I have edited out most of the code to try and find the source of the error without success and now wonder if there is something further required doing with the configuration file, todate the only extensions activated are the two mysql extensions (Which I am not using yet) The extension_dir & session.save_path have both been set.
    Has anyone in this forum covered this ground and can offer a suggestion why the page cannot be displayed?
    Thanks for any assistance in anticipation.
    Last edited by kyberfabrikken; Sep 29, 2010 at 05:46. Reason: php-code tags

  2. #2
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi, and welcome to Sitepoint.

    500 is a generic error from the webserver, which means "something went terribly wrong". In this case, php encountered a fatal error. You can turn on error messages in the browser. I would recommend that you use this for your development site, as it makes it much easier to see what is wrong, in cases like this. In your php.ini file, make sure that display_errors is turned on.

    What you'll find, is that there is a syntax error in your page. That's because you forgot to close the <?php tag with a ?>, before going on to print the </body> tag.

    Use the bb-code markup next time - makes it much easier to read your post. Incidentally, it also shows where your problem is.

  3. #3
    Non-Member Kalon's Avatar
    Join Date
    Aug 2010
    Location
    At my computer
    Posts
    2,012
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't see why you have

    Code:
     
    echo $product->_type;
    when $_type in your class is set as protected.

    You should be using your accessor method

    getProductType().
    Code:
     
     
    echo $product->getProductType();
    If you like, try this Book class and test code to see if your error is related to your code or php configuration.

    <?php
    class Book {
    //properties
    private $title;
    private $author;

    //------------------------------------------------------------

    public function __construct($newTitle, $newAuthor) {
    $this->title = $newTitle;
    $this->author = $newAuthor;
    }

    public function setTitle($newTitle) {
    $this->title = $newTitle;
    }

    public function setAuthor($newAuthor) {
    $this->author = $newAuthor;
    }

    public function getTitle() {
    return $this->title;
    }

    public function getAuthor() {
    return $this->author;
    }

    } //end of class. The above code would normally be stored in a separate php file

    //testing code

    //first create 2 new books
    $mybook1 = new Book('OOP is Great','Fred Smith');
    $mybook2 = new Book('I like OOP','Sam Jones');

    //now display the current values stored in each book
    echo 'Book 1 title = '.$mybook1->getTitle().'<br />';
    echo 'Book 1 author = '.$mybook1->getAuthor().'<br />';
    echo 'Book 2 title = '.$mybook2->getTitle().'<br />';
    echo 'Book 2 author = '.$mybook2->getAuthor().'<br /><br />';

    //now change some values in each book
    $mybook1->setTitle('OOP is Great - 2nd Edition');
    $mybook2->setAuthor('John Smith');

    //now display the current values stored in each book
    echo 'Book 1 title = '.$mybook1->getTitle().'<br />';
    echo 'Book 1 author = '.$mybook1->getAuthor().'<br />';
    echo 'Book 2 title = '.$mybook2->getTitle().'<br />';
    echo 'Book 2 author = '.$mybook2->getAuthor().'<br /><br />';
    ?>

  4. #4
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    989
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    accessors... a completely different topic (and also they're entirely redundant and pointless ).


    @OP it sounds like your IIS set up is wrong, when i used IIS I remember having to modify the web.config file to make it display PHP errors correctly.

  5. #5
    SitePoint Guru
    Join Date
    Jun 2006
    Posts
    638
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Also get PHP 5.3 and up, if you want to really use the OOP.

  6. #6
    SitePoint Member
    Join Date
    Feb 2008
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Smile

    Hi kyberfabrickken, Kalon, TomB & Vali
    Your replies were spot-on!

    kyberfabrickken, I have followed the links through the PHP manual given and written what I guess is belt & braces by adding
    <?php
    echo ini_get('display_errors');
    ?>
    to the top of my product_test file (+ the closing tag (this must have been inadvertantly deleted when I was commenting-out & and removing slashes in a bid to find out what was wrong)
    I also edited the line in my ini file "display_errors = "stderr"". "display_errors = On" & "error_reporting = E_ALL & ~E_NOTICE" were on by default.
    The browser showed a blank screen until I removed the slashes on the echo statement returning the 500 error.

    Kalon, I copied and pasted your "getProductType()" codeline to my file and it now works as expected.

    Vali, I have PHP 5.3 downloaded but the installation file still talks about a file "php5ts.dll" which I cannot find in the unzip PHP folder, a file "php5.dll" was found but whether it can be treated as an alternative I dont know!

    Many thanks to all who answered my post.

  7. #7
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Edward Stephen View Post
    kyberfabrickken, I have followed the links through the PHP manual given and written what I guess is belt & braces by adding
    <?php
    echo ini_get('display_errors');
    ?>
    This doesn't work for parse errors, as the error happens before the file is executed, and so before the ini setting is changed. Better to set it in php.ini.

  8. #8
    Non-Member Kalon's Avatar
    Join Date
    Aug 2010
    Location
    At my computer
    Posts
    2,012
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TomB View Post
    accessors... a completely different topic (and also they're entirely redundant and pointless ).
    I think I can see what you are saying from the point of view that since php is not a compiled language, anyone you give the class to use can change the code to remove accessor methods and access properties directly if they are declred public.

    But I guess I am influenced by my Java programming days where the code is compiled and programmers could not access class properties directly or even see what they were called if accessor methods were used to access properties and all the programmer had was the executable class file and not the source file.

    I guess I still try to use the concept of encapsulation as much as possible in php.

  9. #9
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    989
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    Nothing wrong with encapsulation but accessors are just the same as public properties

    If all you're doing is wrapping class members, it just leads to more verbose code (both ends), higher development time and no real benefit.


    Occasionally, however, they're useful:

    -Interfaces don't support variables so when programming around interfaces and you need the client code to specify a variable an accessor is the only way

    -Because PHP is dynamically typed, setters can be used to enforce types (By type hinting in the parameter)


    I suppose you could argue consistency, but imho, that's not a fair trade off for writing potentially hundreds of lines of redundant code.

  10. #10
    SitePoint Member
    Join Date
    Feb 2008
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Thumbs up

    Hi Kalon, thanks for the bit of oop code, I have copied it into two files test & class and it worked first time as expected.

  11. #11
    SitePoint Member
    Join Date
    Feb 2008
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi can anyone explain the error message that I have on screen?
    PHP Fatal error: Cannot redeclare class Ch2_Product in C:\inetpub\wwwroot\Ch2Visability\ch2_exercises\Product.php on line 3
    I am adding child classes to the original project discussed above and get an error 500 unable to display. I have then backtracked in order to locate the problem (back to the main class)

    Test file
    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.3.org/1999/xhtml">
    <head>
    <title>Experimenting with visability</title>
    <meta http-equiv="content-type"
       content="text/html; charset=iso-8859-1" />
    </head>
    <body>
    <?php
      // include the class file
      require_once '../Ch2/Product.php'; // added to revert back to accessing main class
    //  require_once '../Ch2/Book.php';
    //  require_once '../Ch2/DVD.php';
    
      // create an instance of the all classes
      $product1 = new Ch2_Product('Book', 'PHP Object-Oriented Solutions');  // edited to Ch2_Product
      $product2 = new Ch2_Product('DVD', 'Atonement');             // edited to Ch2_Product
    
      // display the $_type property
    echo '<p>$product1 is a ' . $product1->getProductType();
    echo ' called "' . $product1->getTitle() . '"</p>';
    echo '<p>$product2 is a ' . $product2->getProductType();
    echo ' called "' . $product2->getTitle() . '"</p>';
    ?>
    </body>
    </html>
    This works, I have now introduced one of the child classes with the following changes

    PHP Code:
    // include the class file
      
    require_once '../Ch2/Product.php'// added to revert back to accessing main class
    //  require_once '../Ch2/Book.php';
      
    require_once '../Ch2/DVD.php';     // removed edit slashes to include the file with child class Ch2_DVD

      // create an instance of the all classes
      
    $product1 = new Ch2_Product('Book''PHP Object-Oriented Solutions');  // edited to Ch2_Product
      
    $product2 = new Ch2_DVD('DVD''Atonement');             // edited to Ch2_DVD 
    This change has produced the above error, but I cant see where the class "Ch2_Product" has been redeclaired?
    It is declaired in the file Product.php but where else?

    File Product.php
    PHP Code:
    <?php
    class Ch2_Product
    {
      
    // properties defined here
      
    protected $_type;
      protected 
    $_title;

      
    // constructor
      
    public function __construct($type$title)
      {
        
    $this->_type $type;
        
    $this->_title $title;
      }

      
    // methods defined here
      
    public function getProductType()
      {
        return 
    $this->_type;
      }
      public function 
    getTitle()
      {
        return 
    $this->_title;
      }
    }
    File DVD.php with child class
    PHP Code:
    <?php

    require_once 'Product.php';

    class 
    Ch2_DVD extends Ch2_Product
    {
      
    // class definition goes here
    }
    The child class contains no properties or methods yet which should make it identical to the parent.
    Last edited by SpacePhoenix; Sep 30, 2010 at 09:54. Reason: php and html tags

  12. #12
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,500
    Mentioned
    163 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    Use the bb-code markup next time - makes it much easier to read your post. Incidentally, it also shows where your problem is.
    When you post code, put it between the appropriate bb code tags, please.

  13. #13
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    989
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    check you are not including product.php more than one (or use require_once to include them)

  14. #14
    Non-Member Kalon's Avatar
    Join Date
    Aug 2010
    Location
    At my computer
    Posts
    2,012
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I suspect that not having any methods in DVD.php could be the problem since it is an extension of the Ch2_Product class.


    For Ch2_product to see the properties and methods of the parent class you will need

    Code:
     
    parent::__construct();
    in the constructor of the sub-class along with any other constructor statements for the subclass.

    Try adding at least the above line in the constructor for DVD.php and see if that helps.

    Maybe with nothing in the subclass, php is seeing the subclass as a redeclaration of the parent class.

  15. #15
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    689
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Kalon View Post
    I suspect that not having any methods in DVD.php could be the problem since it is an extension of the Ch2_Product class.


    For Ch2_product to see the properties and methods of the parent class you will need

    Code:
     
    parent::__construct();
    in the constructor of the sub-class along with any other constructor statements for the subclass.

    Try adding at least the above line in the constructor for DVD.php and see if that helps.

    Maybe with nothing in the subclass, php is seeing the subclass as a redeclaration of the parent class.
    Nope nope nope. Perfectly fine to extend a class without adding methods or instance variables. Problem, as already noted by several other posters, is that Product.php is being included more than once.

  16. #16
    Non-Member Kalon's Avatar
    Join Date
    Aug 2010
    Location
    At my computer
    Posts
    2,012
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    Nope nope nope. Perfectly fine to extend a class without adding methods or instance variables. Problem, as already noted by several other posters, is that Product.php is being included more than once.


    I would have thought so as well but since the only change the OP made was uncomment this line

    Code:
    require_once '../Ch2/DVD.php';
    and if there is no previous other include or require of that file elsewhere in the code then that was worth a try.

    Without seeing all the code (which is probably impractical to post) sometimes "brainstorming" possible solutions can help.

  17. #17
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    689
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Understand. And I didn't really want to make things too easy for the original poster. Better to explain the principle and then let the user figure out the details.

    Notice how DVD.php includes the Product.php file.

  18. #18
    SitePoint Member
    Join Date
    Feb 2008
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question

    Hi guido2004, sorry the reference to bb-code markup by kyberfabrikken went over my head - what is a bb-code markup? Are we talking HTML <b></b> bold tags?

    TomB, I have used only require_once to call the main class file "Product.php" I have called it in the test file listed at the top of my code above and again in the child class, Im not sure of what the "require_once" blackbox contains but its name suggests that it protects against the file containing, in this case, the parent class being called twice possibly by checking if certain values are set. However multiple child classes need to call their parents how else can they inherit the parent properties & methods? This condition will continue when the test file is edited and a second child Ch2_Book replaces the direct call to Ch2_Product with an indirect call via the second child class.
    Note:- I have an error message this time instead of the previous 500 error message (not able to display the page) when I add the second child it reverts back to the 500 error. Any suggestions how to avoid declairing the parent class more than once? (unless it goes global!)
    Thanks again in anticipation.

  19. #19
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    689
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    require_once '../Ch2/Product.php';
    vs
    require_once 'Product.php';

    System thinks they two different files and thus includes them twice.

    Once you get past this hurdle take a look at autoloading to see how to implement load on demand functionality.
    http://ca3.php.net/manual/en/language.oop5.autoload.php

  20. #20
    SitePoint Member
    Join Date
    Feb 2008
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Thumbs up

    Hi ahundiak, many thanks for your reply, I have adjusted the "require_once 'Product.php';" to "require_once '../Ch2/Product.php';" in the child file DVD.php and it performs successfully.
    I have then edited the test file to call both child classes as was the original intention and so long as I call the parent class from the child class using a URL from the root directory "'../Ch2/Product.php';" it continues to work.
    This raises another question: since both child classes & the parent class reside in the same directory why can I not call the parent class from the child classes with the shorter "require_once 'Product.php';" after all the "require_once" should not now be confused into thinking the file being called from the two child classes is not the same file? But it does and I get a 500 error?
    Bottom line all calls from child to parent class require to come through the root directory?
    Hope this conveys what I intend to say, best regards.
    P.S. There is a lot to digest in ca3.php.net//language.oop5.autoload.php this will take a little time for me to in. Thanks for pointing me to it.

  21. #21
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,500
    Mentioned
    163 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Edward Stephen View Post
    Hi guido2004, sorry the reference to bb-code markup by kyberfabrikken went over my head - what is a bb-code markup? Are we talking HTML <b></b> bold tags?
    No. If you use 'Go Advanced' instead of using 'Post Quick Reply', you'll find a couple of buttons that allow you to add <code> or <php> tags, and there's even a drop down box with more advanced code tags. Just put your code between those tags.

  22. #22
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    689
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    I was a bit surprised myself that require_once didn't resolve the paths properly. Taking into account multiple operating system and such, it's actually a somewhat difficult problem to solve. You can google for some of the discussions on it.

    The other piece of the puzzle that you will want to look at is setting the include path. Once the include path is set then you can use relative file paths.
    http://ca3.php.net/manual/en/function.ini-set.php

    Assume you have
    /home/user/classes/CH1/ (Some CH1 classes)
    /home/user/classes/CH2/ (Some CH2 classes)

    PHP Code:
    // Point the include path to your classes base directory
    ini_set('include_path','.' PATH_SEPARATOR '/home/user/classes');

    // and then include with
    require_once 'CH2/Product.php'
    Now your classes can live anywhere in the file system.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •