Archive for the ‘PHP’ Category

C# to PHP – Translating my string to object to string C# solution

26 Mar

Early this year I changed jobs where my new workplace uses PHP as its language of choice. As a academic excise I decided to translate the string to object back to string C# code I did here into PHP.

I am very impressed in how easy it was to write in PHP! Instead of using class and method attributes like I did in the C# solution, I wrote a base class to store this functionality. Therefore any class that I want to collapse into a string or be built into a model should inherit this class.

What I really like about PHP over C# is the ability to dynamically build function calls and even object declaration. You can see below that get_input_string and get_array use these language features respectively. This makes it really easy to write code that deals with anonymous classes and objects.

Here is my Template class which provides similar functionality to my static method extensions I wrote in C# here.

class Template {
    private $InputTemplate;
    private $OutputCounterLen;
    private $ArgArray = array();

    public function __construct($argArray, $input_Template, $output_counter_len) {
        $this->InputTemplate = $input_Template;
        $this->ArgArray = $argArray;
        $this->OutputCounterLen = $output_counter_len;
    }

    public function get_input_string() {
        $template = $this->InputTemplate;
        foreach ($this->ArgArray as $key => $argument) {
            $func = "get_$key";
            $val = $this->$func();
            if (strlen($val) > $argument['len']) {
                throw new Exception("Too Long!");
            }
            if (!preg_match($argument['regex'], $val)) {
                throw new Exception("Regex missmatch!");
            }
            $template = str_replace("{".$key."}", $val, $template);
        }
        return $template;
    }

    public function get_array($str) {
        $count = substr($str, 0, $this->OutputCounterLen);
        $str = substr_replace($str, "", 0, $this->OutputCounterLen);
        $arr = array();
        for ($i = 0; $i < $count; $i++) {
                $class = get_class($this);
                $obj = new $class();
                foreach ($this->ArgArray as $key => $value) {
                    $val = substr($str, 0, $this->ArgArray[$key]['len']);
                    $func = "set_$key";
                    $obj->$func(trim($val));
                    $str = substr_replace($str, "", 0, $this->ArgArray[$key]['len']);
            }
            $arr[] = $obj;
        }
        return $arr;
    }
}

Now I have a Template base class that can build a string using the objects variables based on its assigned template. Below is a class the inherits the above template and and declares the maximum length and regular expression constraints of each of the classes properties. I think this part is done more elegantly in my C# solution here because you can clearly see what constraints apply to the property because they are grouped together. As far as I know PHP does not have this functionality so I had to declare these constraints in an array in the constructor of the class.

Note: Each property must have a getter and a setter to work with the Template functions. I do miss the “{ get; set; }” of C# here.

class Foo extends Template {
    private $Bar;
    private $Baz;

    public function __construct($bar = "", $baz = "") {
        $this->Bar = $bar;
        $this->Baz = $baz;

        $argArray['bar'] = array('regex' => "/^[a-zA-Z\s]+$/", 'len' => 10);
        $argArray['baz'] = array('regex' => "/^[a-zA-Z\s]+$/", 'len' => 10);
        parent::__construct($argArray, "{bar} {baz}", 2);
    }

    public function get_bar() {
        return $this->Bar;
    }

    public function get_baz() {
        return $this->Baz;
    }

    public function set_bar($val) {
        return $this->Bar = $val;
    }

    public function set_baz($val) {
        return $this->Baz = $val;
    }
}

Finally to get your string based on the properties of Foo all you need to do is call get_input_string. The echo will print “Hello World” which is based on the template string “{bar} {baz}” declared in class Foo’s constructor.

$fooObj = new Foo("Hello", "World")
echo $fooObj->get_input_string(); //Will print "Hello World"

Also, to get an array of Foo objects from a string passed to to the get_array_method you can use the following. Sadly, this means you need to create a redundant Foo object in order to call get_array. Using PHP 5.3 I could make a static method and use the new late static binding function to get the class name, however I would also need a way of statically declaring the ArgArray containing the property constraints. So this will do for now.

$arr = $fooObj->get_array("3 One 1     One 2     Two 1     Two 2     Three 1    Three 2    ");

echo $arr[0]->get_bar(); //Will print "One 1"
echo $arr[0]->get_baz(); //Will print "One 2"

echo $arr[1]->get_bar(); //Will print "Two 1"
echo $arr[1]->get_baz(); //Will print "Two 2"

echo $arr[2]->get_bar(); //Will print "Three 1"
echo $arr[2]->get_baz(); //Will print "Three 2"

As you can see the above PHP solution is written in significantly less lines of code then its C# counterpart. There are some parts of the C# solution a prefer over the PHP solution, namely the class and method attributes. However I have to say overall I prefer my PHP solution. To be idiomatic I had to change the PHP solution quite a bit. I reckon I could take the same approach in C# and it will yield less code then the original however I still thing the PHP solution will surpass!

Oh and this post is in no way saying that PHP is better then C# all the time! I just think in this particular case it was easier and, in my opinion, a better solution in PHP.

 
Comments Off

Posted in PHP