0

I'm new to PHP and met with a little problem.

I think I was previously unclear and we did some changes so let me edit this :

In this part, we work on 2 classes :

First one a Singleton

<?php

class Model {

    private $_handle = null;

    private function __construct()
    {
        $this->_handle = array ('0'=>'2011,2015','1'=>[],'2'=>["man","woman"],'3'=>'21,55');
    }

    public function __clone()
    {

    }

    public static function getInstance()
    {
        static $_instance = null;

        if ($_instance === null) {
            $_instance = new self();
        }

        return $_instance;
    }

    public function getObj()
    {
        return $this->_handle;
    }

public function setObj($value, $index)
    {
        $this->_handle[$index]= $value;
    }

}

And another class which extends from it.

<?php

include "QueryBuilder.php";

class globalModel extends Model
{
    public function valueSettings($type, $val)
{
        switch($type) 
{
            case 'ages':
                $this->setObj($val, 3);
                break;
            case 'sexe':
                $this->setObj($val, 2);
                break;
            case 'countries':
                $this->setObj($val, 1);
                break;
            case 'date':
                $this->setObj($val, 0);
                break;  
        }
    }   

    }

    public function Main()
    {
        $this->valueSettings($_POST['type'],$_POST['value']);
        $value = $this->getInstance()->getObj();
        //Build Query Sentence
//        $QB = new QueryBuilder();
//        $fullQuery = $QB->QueryBuild($_POST['tab'], $value);
//
//        echo $fullQuery;
    }
}

We did many experimentation and we found that since the _construct is being ran over and over again, the array we set at the beginning is being reset as construct is being called. That's why we try to use a Singleton here and I think it should be good.

But here, the code doesn't work at all ...

Without a singleton, the Array gets updated for the last value we give it. But if we call valueSettings again, it'll act as if we never called it before because it'll take the value from __construct again.

So the questions would be, is it good idea to use a Singleton ? If yes why does this code isn't working ? =( If no, how should we set the array the first time ? Outside of a function ?

MisterYUE
  • 41
  • 1
  • 7
  • 1
    what you meant by GLOBALS??? – JTheDev Dec 30 '15 at 12:55
  • 1
    Please give a bit more context. How do you call the function, and what do you (want to) do with the return value? BTW, there is a built-in `json_encode` function. Don't build JSON manually like this. – trincot Dec 30 '15 at 12:57
  • my mistake, was trying something, forgot to remove the Globals – MisterYUE Dec 30 '15 at 12:58
  • I want to call this function in another function main(). – MisterYUE Dec 30 '15 at 12:59
  • Variable assignments, array indexes and scopes don't seem to line up to anything we can accurately work with. Could you perhaps explain what your expected input and output of this function is? We can work with that much more accurately. – developerjack Dec 30 '15 at 13:08
  • Variables aren't expanded inside single quotes. See http://stackoverflow.com/questions/3446216/what-is-the-difference-between-single-quoted-and-double-quoted-strings-in-php – Barmar Dec 30 '15 at 13:10
  • I can't figure out what you're trying to do. The function returns a new associative array, it doesn't modify an existing array. Did you mean to pass in `$value` as an argument so it can be modified? – Barmar Dec 30 '15 at 13:13
  • ok, I think I explained badly. So basically I have an array, and everytime the function is ran, the function should fill my array according to the switch case. Maybe I should have written "return $value" to make it simpler – MisterYUE Dec 30 '15 at 13:15
  • I wanted to pass $value as an arugment but my mate implied it was a bad idea haha. But the problem remains that the code restarts everytime with array('','','','') so it gets emptied. I was thinking of Apc_store but there are some problems with memory thing – MisterYUE Dec 30 '15 at 13:17
  • No, no, not apc_store. This is just a matter of using global variables correctly when they are manipulated inside a function. Check out globals keyword, and calling by reference. Two ways to deal with this. – trincot Dec 30 '15 at 13:36
  • Are you going to make further changes to the code in your question? Please let us know when it is final, so we can make an answer that has something to do with your code, and not with something that is not there any more. – trincot Dec 31 '15 at 15:13

3 Answers3

0

I am really not sure what you want to achieve with your code, but let me make 2 comments that might help:

  1. the dot operator . in PHP is used to concatenate strings. If you want to access members of an object you need to use ->. I am just assuming here, but Its a common mistake if you come from C++, I stumbled over this too :)
  2. If you want to work with JSON I recommend using the build in functions json_encode() and json_decode(). Just create an array with your needed elements and use json_encode to convert them to JSON notation. see also http://php.net/manual/de/function.json-encode.php
Erik Kalkoken
  • 30,467
  • 8
  • 79
  • 114
0

This is the best guess I have of what you're trying to do:

public function JsonParse($type, $tab, $val, $value)
{
    $onglet = $tab;
    switch($type) {
    case 'age':
        $value[3] = $val;
        break;
    case 'sexe':
        $value[2] = $val;
        break;
    case 'nationalité':
        $value[1] = $val;
        break;
    case 'année':
        $value[0] = $val;
        break;
    }
    $result = array("onglet"=>$onglet, "value"=>$value};
    return $result;
}

Each time you call this function, it inserts $val into the appropriate place in the $value array, and then returns this new array as the value element of the resulting array. So you can do:

$value = array('', '', '', '');
$new = JsonParse('age', $onglet, 10, $value);
$value = new['value'];

The last line updates $value with the new array returned by the function.

If you want to print it as JSON, you can call json_encode in the caller. Never try to create JSON by hand, there are too many special cases you need to deal with -- just use the built-in functions for it.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • yes, that's basically what I try to do, but the other problem would be that my mate is sending me only ONE value at a time, so everytime I run this function, only one of the array index would be filled. Afterward, since I'll be recreating the array, it'd be empty again since I have $value = array('','','',''), I don't know how I should create my $value array so it actually saves the index's values – MisterYUE Dec 30 '15 at 13:34
  • Just define $value = array(); Why are you write index number of array? Array will manage index by itself. – Ravi Hirani Dec 30 '15 at 14:04
  • @MisterYUE How is the the `$value` array that you show related to the `value' element of the associative array returned by `JsonParse`? – Barmar Dec 30 '15 at 14:07
  • I've updated the answer to show how you can get the updated `$value` array from the function. – Barmar Dec 30 '15 at 14:10
  • By the way, it looks like the array should have 4 elements, not 3: age, sex, nationality, and year – Barmar Dec 30 '15 at 14:11
  • sorry for being very uncleared the first time, I made a big edit on the very first question – MisterYUE Dec 30 '15 at 15:29
0

To create JSON use json_encode. It seems also more practical to delay the conversion to JSON to the moment when all data has been collected, so you should not do the conversion repeatedly in that function.

Your function could also benefit from array_search, instead of using switch.

Finally, since you are interested in a JSON containing both the values and the tab (onglet), it will be practical to have the object structured that way from the beginning:

{ onglet: '', value: ['', '', '', ''] }

Or, in PHP syntax:

(object) Array(
    "onglet" => '',
    "value" => array('','','','')
);

Although you can work with global variables inside functions with the global keyword, I would suggest passing the above suggested object as a by reference argument.

Here is some example code.

function collect(&$obj, $type, $tab, $val)
{
    $obj->onglet = $tab;
    $index = array_search($type, array('année', 'nationalité', 'sexe', 'age'));
    if ($index !== false) { // valid $type:
        $obj->value[$index] = $val;
    }
    return $obj; // not really necessary, as $obj is modified in-place.
}       

// the global object in which to collect the data:
$obj = (object) Array(
    "onglet" => '',
    "value" => array('','','','')
);

// collect the data; we don't use return value:
collect($obj, 'année', 'premier', '2015');
collect($obj, 'nationalité', 'premier', 'FR');
collect($obj, 'sexe', 'premier', 'masculin');
collect($obj, 'age', 'premier', '21');

// convert $obj to JSON:
echo json_encode($obj);

// output: 
//   {"onglet":"premier","value":["2015","FR","masculin","21"]}

Persist data across requests:

Now if you don't have all the information during one request, you probably should use session scope variables.

Let's say every element is added by passing URL arguments type, tab, val, then you can persist the data during the session by using session_start and $_SESSION[]:

session_start();
if (!isset($_SESSION["obj"])) { // first time, initialise:
    $_SESSION["obj"] = (object) Array(
        "onglet" => '',
        "value" => array('','','','')
    );
}

// The session variable might already have data from previous request.
// Add the currently provided arguments to it:
collect($_SESSION["obj"], $_GET["type"], $_GET["tab"], $_GET["val"]);

echo json_encode($_SESSION["obj"]);
trincot
  • 317,000
  • 35
  • 244
  • 286