www.webdeveloper.com
Results 1 to 7 of 7

Thread: [RESOLVED] How to use php classes between other classes

  1. #1
    Join Date
    Dec 2013
    Location
    Melbourne, Australia
    Posts
    26

    resolved [RESOLVED] How to use php classes between other classes

    I know the basics of PHP and have only ever used it to debug Wordpress code generally but now I want to write my own little program to download an email and process an attachment and I have decided to try using classes as I have a basic understanding of OO programming.

    SO PLEASE READ: I am a novice! I have a slim grasp of OOP

    My issue is that I have created a function called printStatus() so I can toggle on/off output of comments. I was looking at this and I'm not sure how or if it would fit into a class structure or if I need to include this function in every other class I create?

    Basically - If I created a class, I would need to make it available to all other classes (i.e. a global class) but I'm not sure if that is achievable.

    My Question's are:

    1. Do I have to pass a reference to the printOutput class to and from every class I use to have it available to me OR can I declare it globally to make it available to all classes OR do I need to include the same function in every class I create?
    2. I've created a MySQL Connection class and I am passing that into each object for use - should (can I) declare it globally and just make it available to all classes?

    Thanks for the 101.

    Here is my code, am I going down the right path?: (see specifically, references to printStatus())

    PS - $formatoutput->printStatus() does not work within other classes - I'm looking to understand what structure is required to make it work.


    class.formatoutput.php:
    PHP Code:
        class formatOutput {
            
            var 
    $debug true;
            
            function 
    printStatus($text$html true) {
                
                if (
    $debug) {
                    echo 
    $text;
                    echo 
    $html?"<br/>\n":"\n"
                }
            }
            
            function 
    printObjectStatus($object$html true) {
        
                if (
    $debug) {
                    echo 
    '<pre>';
                    echo 
    $text;
                    echo 
    $html?"</pre><br/>\n":"</pre>\n"
                }    
            }
        } 
    class.connection.php:
    PHP Code:
        class Connection 
        
    {
            var 
    $db_host "host";
            var 
    $db_name "name";
            var 
    $db_user "user";
            var 
    $db_pass "pass";
            var 
    $db_conn;
        
            function 
    connectToDatabase() {
        
                
    $db_conn mysqli_connect($this->db_host$this->db_user$this->db_pass$this->db_name);
        
                if (!
    $db_conn) {
                    die(
    'Connect Error (' mysqli_connect_errno() . ') ' mysqli_connect_error());
                }
                else
                {
                    
    $this->db_conn $db_conn;
                    
    $formatoutput->printStatus"Connection established");
                }
                return 
    $this->db_conn;
        
            }
        
            function 
    closeConnection() {
                
    mysqli_close($this->db_conn);
                
    $formatoutput->printStatus"Connection closed");
            }
        
        } 
    class.customer.php:
    PHP Code:
        class Customer {
        
            var 
    $customer_id;
            var 
    $customer_name;
        
        
            function 
    getCustomer($connection$user_id) {
        
                
    $query "SELECT id, name FROM customer WHERE user_id=$user_id";
                
                
    $result mysqli_query($connection$query);
                
                if(
    $result === FALSE) {
                    die(
    'Connect Error (' mysqli_errno() . ') ' mysqli_error());
                }
        
                
    $row_count mysqli_field_count($connection);
                
    $formatoutput->printStatus"COUNT: (".$count.")");
        
            }
        
        } 
    index.php:

    PHP Code:
        include 'class.formatoutput.php';
        include 
    'class.connection.php'
        include 
    'class.customer.php'
        
        
    $formatoutput = new formatOutput();
        
    $formatoutput->printStatus('Start new Connection()');
        
    $connection = new Connection();
        
    $connection->connectToDatabase();
        
    $customer = new Customer();
        
    $customer->getCustomer($connection->db_conn"1");
        
    $connection->closeConnection(); 

  2. #2
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,521
    I would try to avoid injecting such a dependency into my classes. As much as possible, you want to keep each class focused on its job only. Every time you require it to depend on custom code that exists somewhere else, you tightly couple it to that "foreign" code, meaning you always have to have both pieces together -- yet that is not obvious from your class's public interface.

    If you do need to use another object within a class, then I generally prefer to make that obvious by requiring that it be passed into the class's constructor, using type-hinting.
    PHP Code:
    <?php

    class Example
    {
        private 
    $formatOutput;
        
        public function 
    __construct(FormatOutput $formatOutput)
        {
            
    $this->formatOutput $formatOutput;
        }
        
        public function 
    test($text)
        {
            
    $this->formatOutput->printStatus($text);
        }
    }

    // then

    $fo = new FormatOutput();
    $test = new Example($fo);
    $test->test("This is a test");

    // or

    $test2 = new Example(new FormatOutput());
    $test2->test("It is only a test");
    In this particular case, I'd probably be more likely myself to just make use of error_log() and tail the applicable PHP error log file.
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  3. #3
    Join Date
    Dec 2013
    Location
    Melbourne, Australia
    Posts
    26
    Thanks for the response .. it makes sense.

    As I said, I'm just a novice so this is purely for educational purposes (to see the result of each call) - Once we get to production, I imagine I will turn that off and not require it... I'm probably over doing it but it's basically a checkpoint at almost every step to see if I'm going along the right track (I am basically learning as I go)

    So you're post suggests that it be made obvious by passing it to the constructor...

    So if I was to take that on board for the mysql connection object, my classes would look like this:

    PHP Code:

    class Example 

        private 
    $formatOutput
        private 
    $dbConnection

         
        public function 
    __construct($dbConnectionFormatOutput $formatOutput
        { 
            
    $this->formatOutput $formatOutput
            
    $this->dbConnection $dbConnection
        } 

        function 
    getCustomer($user_id) { 
         
            
    $query "SELECT id, name FROM customer WHERE user_id=$user_id"
                 
            
    $result mysqli_query($dbConnection$query); 
                 
            if(
    $result === FALSE) { 
                die(
    'Connect Error (' mysqli_errno() . ') ' mysqli_error()); 
            } 
         
            
    $row_count mysqli_field_count($dbConnection); 
            
    $this->formatOutput->printStatus"COUNT: (".$count.")"); 
         
        } 



    // then 

    $fo = new FormatOutput(); 
    $conn = new Connection();
    $test = new Example($conn$fo); 
    $test->getCustomer($user_id); 
    Have I understood correctly and implemented in your suggested (not ideal) way? (not ideal because I am still tightly coupling classes?

  4. #4
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,521
    DB objects getting passed around like that is a quite common pattern. I might consider having your database class extend the MySQLI class, then classes that use it can simply type-hint for MySQLI if they only need its methods, or for your specific child class if they need any new (or overridden) methods defined there.
    PHP Code:
    <?php

    class MyDB extends mysqli
    {
        private 
    $dbHost 'localhost';
        private 
    $dbName 'test';
        private 
    $dbUser 'foo';
        private 
    $dbPass 'bAr';

        public function 
    __construct()
        {
            
    parent::__construct(
                
    $this->dbHost,
                
    $this->dbUser,
                
    $this->dbPass,
                
    $this->dbName
            
    );
        }
    }

    class 
    Example
    {
        private 
    $db;
        public function 
    __construct(mysqli $db)
        {
            
    $this->db $db;
        }
    }

    $db = new MyDB();
    $test = new Example($db);
    $test2 = new Example($db); // no need to create other DB object (usually)
    When you're starting to feel a bit comfy with this kind of stuff, grab yourself a copy of Matt Zandstra's PHP 5 Objects, Patterns, and Practice and really start absorbing it.
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  5. #5
    Join Date
    Dec 2011
    Location
    Centurion, South Africa
    Posts
    795
    I just want to mention something I haven't seen here so far, but you also have the ability to import globally defined variables into your functions, using the global keyword:

    http://www.php.net/manual/en/languag...bles.scope.php

    Code:
    <?php
    
    	class Connection
    	{
    		function connectToDatabase()
    		{
    		}
    		function closeConnection()
    		{
    		}
    	}
    	$connection = new Connection();
    
    	class formatOutput 
    	{
    		function printStatus($text, $html = true) 
    		{
    		}
    		function printObjectStatus($object, $html = true) 
    		{
    		}
    	}
    	$formatoutput = new formatOutput();
    
    	class Customer 
    	{
    		function getCustomer($user_id) 
    		{
    			global $connection, $formatoutput;
    
    			$connection->connectToDatabase();
    			$formatoutput->printStatus('Example');
    		}
    	}
    
    ?>
    Obviously this would suggest you use predefined class instances by the same name, which would make sense to begin with. Also, unless you have many connections to your database, which is unlikely, why not define the variable inside the file that defines the class (centralized configuration).

  6. #6
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,521
    Noooooooo....don't use global! Now you're really injecting external dependencies into your class.

    In fact, just don't use the global keyword ever, and your debugging/re-using life will be much simpler.
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  7. #7
    Join Date
    Dec 2013
    Location
    Melbourne, Australia
    Posts
    26
    Thanks guys,

    More than enough information in here to give me a pretty good grasp on how to move forwards.

    I have used global before and I take on board your comments.

    Thanks

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

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



Recent Articles