Search code examples
phpoopphp-5.3

Pass method as constructor parameter


I'm trying to write a class for an API and I need my constructor to use some methods as parameters (because I'll be getting the data from a csv).. I'm doing some tests with this:

class API {

    public $a;
    public $b;

    function __construct(){
        $this->a = setA($a);
        $this->b = setB($b);
    }

    function setA($a){
        $a = "X";
    }

    function setB($b){
        $b = "Y";
    }
}

but it's not working. Is this even possible or correct?

Edit: As requested by user Halcyon.

The original design was made on various functions that interacted with each other. It wasn't the best because data was being fetched over and over instead of read from 1 place only.

The methods for the csv and the json are:

function getJsonData(){
    $stream = fopen('php://input', 'rb');
    $json = stream_get_contents($stream);
    fclose($stream);
    $order_json_data = json_decode($json, true);
    return $order_json_data;
}

function getProductsTable($csvFile = '', $delimiter = ','){
    if (!file_exists($csvFile) || !is_readable($csvFile))
        echo 'File not here';

    $header = NULL;
    $data = array();

    if (($handle = fopen($csvFile, 'r')) !== FALSE){
        while (($row = fgetcsv($handle, 100, $delimiter)) !== FALSE){
            if (!$header)
                $header = $row;

            else if($row[0] != ''){
                $row = array_merge(array_slice($row,0,2), array_filter(array_slice($row, 2)));
                $sku = $row[0];
                $data[$sku]['productCode'] = $row[1];
                $data[$sku]['Description'] = $row[2];
            }
        }

        fclose($handle);
    }

    array_change_key_case($data, CASE_LOWER);
    return $data;
}

Edit: Including the index file where I'm testing the object.

<?php
require_once 'helpers/API.php';

if (in_array($_GET['action'],array('insertOrder','updateOrder'))){
    $api = new API();

    file_put_contents('debug/debug_info.txt', "Object response: {$api->a}, {$api->b}", FILE_APPEND | LOCK_EX);
}

Solution

  • Some things are wrong with the code. Here is a couple examples to show different approaches:

    -Example 1

    class Foo {
    
        public $a;
        public $b;
    
        function __construct(){
            $this->setA();
            $this->setB();
        }
    
        function setA(){
            $this->a = "X";
        }
    
        function setB(){
            $this->b = "Y";
        }
    }
    

    -Example 2

    class Foo {
    
        public $a;
        public $b;
    
        function __construct(){
            $this->a = $this->setA();
            $this->b = $this->setB();
        }
    
        function setA(){
            return "X";
        }
    
        function setB(){
            return "Y";
        }
    }
    

    Note that your code is more like the second example, but it didn't work because the function is not returning anything (and it's missing $this).


    I don't know what $a and $b are, or if you want to set the values from within the class (if they are a constant or something like that), but I'd like to draw your attention to an important aspect of the second example - especially if you are really designing an API. In OOP, we usually have getters and setters. And they are basically used when we encapsulate our class. This is an example of an ecapsulated class:

    class Bar{
        private $a;
        public function getA(){ return $this->a; }
        public function setA($a){ $this->a = $a; }
    }
    

    Note that $a is private, so we don't have access to it directly out of the class. We have to use the methods. That way we can control the access for that attribute, do some validation, etc. (If well designed) This gives us opportunity to further change the implementation of the way the values are get/set without having to look for occurrences of them in the entire project. If in the future you decide that $a can only have numbers, just change the setter.

    It really depends on what $a is. You could also have a __construct to initialize this variable. There are many different ways to do the same thing. Anyway, take a look at Why use getters and setters?.