1

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);
}
Onilol
  • 1,315
  • 16
  • 41

3 Answers3

1

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?.

Community
  • 1
  • 1
FirstOne
  • 6,033
  • 7
  • 26
  • 45
0

There is an error in your code:

class API {

 public $a;
 public $b;

 function __construct($a=null, $b=null){
    $this->a = $a;
    $this->b = $b;
 }

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

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

Reference also the object methods and avoid using non declared variables in the function scope.

$api = new Api("test", "another value" );
Evhz
  • 8,852
  • 9
  • 51
  • 69
  • Didn't work here.. Perhaps I'm testing it wrong. Updating the question. – Onilol Mar 07 '16 at 12:43
  • Your setA and setB functions don't actually do anything. You should either return the values or set the object properties in the functions. – purpleninja Mar 07 '16 at 12:54
  • This has some things that are wrong: 1- Since you are setting the value of `$a` to a function, you HAVE to return something in that function. 2- in `function setA()`, `$a = 'X';` means nothing, it should be `$this->a = 'X';`. But again, this wouldn't be necessary with return. So, you should either change `$this->a = $this->setA();` to just `$this->setA();` and use `$this->a = 'X';` in the function **or** change `$a = 'X';` to `return 'X;'`. – FirstOne Mar 07 '16 at 12:55
  • @FirstOne that did the trick ! I'll keep both statements. Thanks. Also.. is it bad design if I make call another method from the setA or setB ? – Onilol Mar 07 '16 at 13:01
  • @Onilol, what do you mean by keeping both? One is basically not needed if you use the other (use return AND setting the value in the function) – FirstOne Mar 07 '16 at 13:03
  • @FirstOne `$this->a = 'X'` and `return 'X'`. You'll make an official answer or who do I give it to? – Onilol Mar 07 '16 at 13:04
  • @FirstOne Be my guest ;) – Onilol Mar 07 '16 at 13:11
  • @Karlos, you aren't paying attention. Change `$this->b = $this->setB( $b );` to `$this->setB($b);` (and same with `$a`). You are **not** using `return` in the function. – FirstOne Mar 07 '16 at 13:25
0

I don't understood why it need, but you're create callable with this way:

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

Now, you're can use

$propertyWithCallable = $object->a;
$propertyWithCallable();
Arthur
  • 2,869
  • 14
  • 25