Checking which function is true and false - php

Sorry for the terrible headline, let me try to explain below.
I have written a bunch of small functions that either returns true or false.
validateName()
validateEmail()
validateAddr()
validateBirtd()
validateUsername()
Now I am looping through a lot of data imported with a CSV file, and checkin which data is valid or not (returns true or false).
I do it this way:
if (validateName($data[0]) == true AND validateEmail($data[1]) == true AND validateAddr($data[3]) == true AND validateBirtd($data[5]) == true AND validateUsername($data[6])==true) {
// create array to import etc etc
}else{
// create other array with data who failed validation, to show user later..etc etc
}
My question is - is there a more clever way to do this? Would it be possible to create a list of for each failed validation ? Say 3 entrys has fails the validateEmail() function, and 10 both fails validateEmail and validateName().
Would there be a way for me to sort this so I can tell the user "these entrys failed email validation" and "these entrys failed Name and email validation".
I thought about validating one field at a time, but this way I would have duplicates if one entry has more than one validation error.
Would be cool if there was some kind of logic that I don't know of where I could do this

You could create a function.
function validate($data) {
$errors = array();
$fields = array('Name', 'Email', 'Addr', 'Birtd', 'UserName');
foreach ($fields as $i => $field) {
$func = 'validate'.$field;
if (!$func($data[$i])) {
$errors[] = $field;
}
}
return $errors;
}
$errors = validate($data);
if (empty($errors)) {
// create array to import etc etc
} else {
// errors
echo 'There are errors with ' . implode(',', $errors);
}

You can use Iterators to get CSV content and filter at the same time. you can also add different callback to each CSV index
Example
$csv = new CSVFilter(new CSVIterator("log.txt"));
$csv->addFilter(0, "validateName"); //<------------ Means validate Index at 0
$csv->addFilter(1, "validateEmail");
$csv->addFilter(2, "validateAddr");
$csv->addFilter(3, "validateBirtd");
$csv->addFilter(4, "validateName");
$csv->addFilter(5, "validateUsername");
foreach ( $csv as $data ) {
var_dump($data);
}
//To get Errors
var_dump($csv->getErrors());
CSV Filter
class CSVFilter extends FilterIterator {
protected $filter = array();
protected $errors = array();
public function __construct(Iterator $iterator) {
parent::__construct($iterator);
}
public function addFilter($index, Callable $callable) {
$this->filter[$index] = $callable;
$this->errors[$callable] = 0;
}
public function getErrors() {
return $this->errors;
}
public function accept() {
$line = $this->getInnerIterator()->current();
$x = true;
foreach ($this->filter as $key => $var ) {
if (isset($line[$key])) {
$func = $this->filter[$key];
$func($var) or $this->errors[$func] ++ and $x = false;
}
}
return $x;
}
}
CSVIterator
class CSVIterator implements \Iterator {
protected $fileHandle;
protected $line;
protected $i;
public function __construct($fileName) {
if (! $this->fileHandle = fopen($fileName, 'r')) {
throw new \RuntimeException('Couldn\'t open file "' . $fileName . '"');
}
}
public function rewind() {
fseek($this->fileHandle, 0);
$this->line = fgetcsv($this->fileHandle);
$this->i = 0;
}
public function valid() {
return false !== $this->line;
}
public function current() {
return array_map("trim", $this->line);
}
public function key() {
return $this->i;
}
public function next() {
if (false !== $this->line) {
$this->line = fgetcsv($this->fileHandle);
$this->i ++;
}
}
public function __destruct() {
fclose($this->fileHandle);
}
}
Simple Random Functions
function validateName($var) {
return mt_rand(0, 5);
}
function validateEmail($var) {
return mt_rand(0, 5);
}
function validateAddr($var) {
return mt_rand(0, 5);
}
function validateBirtd($var) {
return mt_rand(0, 5);
}
function validateUsername($var) {
return mt_rand(0, 5);
}

If you something a little more encapsulated, you can try this. It allows you to write different validators for each CSV file you may be validating. Additionally, you could write methods in either class that would allow you to perform additional tasks on each row. I just find it a little cleaner and easier to maintain than having a bunch of globally-named functions.
Note: I'm obviously using some pretty basic validator examples and exceptions. The idea here is that I'm providing a layout for you to follow; you can customize any specific behaviors however you'd like.
usage
$c = new UserCsvValidator('user_data.csv');
try {
$c->validate();
}
catch (Exception $e) {
echo $e->getMessage();
}
implementation; parent class
<?php
class CsvValidator {
private $filename;
private $fh;
protected $fields = array();
public function validate__construct($filename, ) {
$this->filename = $filename;
// open file
if ( ($this->fh = fopen($this->filename, 'r')) === false) {
throw new Exception("could not open file: {$this->filename}");
}
}
public function validate() {
while( ($row=fgetcsv($this->fh)) !== false) {
// create hash
if ( ($hash = array_combine($this->fields, $row)) === false) {
throw new Exception("invalid row" . print_r($row, true));
}
// validate
foreach ($hash as $field => $value) {
// determine method call
$method = "validate_{$field}";
if (!method_exists($this, $method)) {
throw new Exception("validation method not defined: {$method}");
}
// validate the field
if (call_user_func(array($this, $method), $value) === false) {
throw new Exception("invalid value for {$field}: {$value}");
}
}
}
}
}
implementation; subclass
<?php
class UserCsvValidator extends CsvValidator {
protected $fields = array('name', 'email', 'address', 'birth_date', 'username');
// example functions for each field
protected function validate_name($value) {
return !empty($value);
}
protected function validate_email($value) {
return strpos($value, '#') !== false;
}
protected function validate_address($value) {
return !empty($value);
}
protected function validate_birth_date($value) {
return date('Y-m-d', strtotime($value)) == $value;
}
protected function validate_username($value) {
return !empty($value);
}
}

Related

PHP Binary Tree Recursive Traversal Infinite Loop Issue

I have a binary tree and node class that can create nodes and then recursively traverse the root for pre, post and in-order node orders. This code works when in JS, but for some reason infinitely loops with a warning of "Cannot use '$this' in non-object context." when returning $this in the addSide() function. What is causing this infinite loop, and how can I fix it?
<?php
class Node {
public $value;
public $right = null;
public $left = null;
function __constructor($value) {
$this->value = $value;
}
}
class BinaryTree {
public $root;
function __constructor() {}
function create($value) {
$newNode = new Node($value);
if (!$this->root) {
$this->root = $newNode;
return $this; //no warning
}
$current = $this->root;
function addSide($side, $current, $newNode) {
if (!$current->$side) {
$current->$side = $newNode;
return $this; //Warning: "Cannot use '$this' in non-object context."
}
$current = $current->$side;
};
while (true) {
if ($value === $current->value) return $this;
if ($value < $current->value) addSide("left", $current, $newNode);
else addSide("right", $current, $newNode);
}
}
function preOrder() {
$visited = [];
$current = $this->root;
function traversePreOrder($node) {
array_push($visited, $node->value);
if ($node->left) traversePreOrder($node->left);
if ($node->right) traversePreOrder($node->right);
};
traversePreOrder($current);
return $visited;
}
function postOrder() {
$visited = [];
$current = $this->root;
function traversePostOrder($node) {
if ($node->left) traversePostOrder($node->left);
if ($node->right) traversePostOrder($node->right);
array_push($visited, $node->value);
};
traversePostOrder($current);
return $visited;
}
function inOrder() {
$visited = [];
$current = $this->root;
function traverseInOrder($node) {
if ($node->left) traverseInOrder($node->left);
array_push($visited, $node->value);
if ($node->right) traverseInOrder($node->right);
};
traverseInOrder($current);
return $visited;
}
}
$tree = new BinaryTree();
$tree->create(50);
$tree->create(30);
$tree->create(45);
$tree->create(12);
$tree->create(29);
echo("inOrder: ". $tree->inOrder());
echo("preOrder: ". $tree->preOrder());
echo("postOrder: ". $tree->postOrder());
Since you don't seem to be from a PHP background, here are some of the things to note down:
It is __construct() and not __constructor(). This served to be a major problem in the code during value comparisons.
No need to create functions inside functions. This can lead to cannot redeclare function issues when a method is called twice.
When calling a method from another method inside a class, $this-> is necessary unless the function being called is an inbuilt function in PHP or at least available during code execution.
You seem to be creating a Binary Search Tree instead of just a Binary Tree.
Pass $visited by reference when collecting values during traversal.
You can't print arrays using echo. Use print_r() or use implode() to convert the array to string using a delimiter(say ,) and then print it using echo.
In create(), you sometimes return a node and sometimes $this. Both are not the same. Former one is an object of the Node class and the latter one is the object of the BinaryTree class.
In create() method, you simply need to traverse left or right from the current code according to the given value, which can be achieved using a simple while loop.
Corrected Code:
<?php
class Node {
public $value;
public $right = null;
public $left = null;
function __construct($value) {
$this->value = $value;
}
}
class BinaryTree {
public $root;
function __construct() {
$this->root = null;
}
function create($value) {
$newNode = new Node($value);
if ($this->root === null) {
$this->root = $newNode;
return $newNode; //no warning
}
$current = $this->root;
while($current !== null){
if($current->value > $value){
if($current->left === null){
$current->left = $newNode;
break;
}else{
$current = $current->left;
}
}else if($current->value < $value){
if($current->right === null){
$current->right = $newNode;
break;
}else{
$current = $current->right;
}
}else{
throw new \Exception("Node with $value already exists.");
}
}
return $newNode;
}
function preOrder() {
$visited = [];
$current = $this->root;
$this->traversePreOrder($current,$visited);
return $visited;
}
function traversePreOrder($node,&$visited) {
array_push($visited, $node->value);
if ($node->left !== null) $this->traversePreOrder($node->left,$visited);
if ($node->right !== null) $this->traversePreOrder($node->right,$visited);
}
function postOrder() {
$visited = [];
$current = $this->root;
$this->traversePostOrder($current,$visited);
return $visited;
}
function traversePostOrder($node,&$visited) {
if ($node->left !== null) $this->traversePostOrder($node->left,$visited);
if ($node->right !== null) $this->traversePostOrder($node->right,$visited);
array_push($visited, $node->value);
}
function inOrder() {
$visited = [];
$current = $this->root;
$this->traverseInOrder($current,$visited);
return $visited;
}
function traverseInOrder($node,&$visited) {
if ($node->left != null) $this->traverseInOrder($node->left,$visited);
array_push($visited, $node->value);
if ($node->right !== null) $this->traverseInOrder($node->right,$visited);
}
}
$tree = new BinaryTree();
$tree->create(50);
$tree->create(30);
$tree->create(45);
$tree->create(12);
$tree->create(29);
echo "inOrder: ". implode(",",$tree->inOrder()),PHP_EOL;
echo "preOrder: ". implode(",",$tree->preOrder()),PHP_EOL;
echo "postOrder: ". implode(",",$tree->postOrder()),PHP_EOL;
Online Demo

Decorate an Iterator in PHP - enable skipping

I have a class that is basically a decorator for PHP's DirectoryIterator. Each file's contents are processed by the class and then returned by the current() method. Currently, when the file is a dot file or the file cannot be processed, I return false from the current() method. But I would rather like to skip the dot- and unprocessable files, and only return processed data.
P.S. The code below is a simplified example. I don't want to pre-process all files in the constructor.
class Pages implements \Iterator
{
public function __construct(string $path)
{
$this->di = new \DirectoryIterator($path);
}
public function rewind() {
return $this->di->rewind();
}
public function current() {
$file = $this->di->current();
if($file->isDot()) {
return false;
}
$content = file_get_contents($file->getPathName());
if($content === 'Cannot be processed!') {
return false;
}
return $content;
}
public function key() {
return $this->di->key();
}
public function next() {
return $this->di->next();
}
public function valid() {
return $this->di->valid();
}
}
You can greatly simplify the code of your own answer by extending the already existing abstract PHP class FilterIterator :
class DirectoryFilterIterator
extends FilterIterator
{
public function __construct(string $path) {
parent::__construct(new DirectoryIterator($path));
}
public function accept() : bool {
$current = parent::current();
// let's not only ensure it's not a dot but that it's an actual readable file
if(!$current->isFile() || !$current->isReadable()) {
return false;
}
else {
$contents = file_get_contents($current->getPathname());
if($contents === 'Some value') {
return false;
}
}
return true;
}
}
foreach(new DirectoryFilterIterator('.') as $key => $value) {
echo "$key -> $value\n";
}
As you can also see, instead of merely ensuring that the item is not a dot, I ensure the item is an actual readable file as I think that is a little more robust for your intentions.
PS: As your original intention was to create a decorator/wrapper you can of course alter the constructor of DirectoryFilterIterator to accept a DirectoryIterator instead:
public function __construct(DirectoryIterator $it) {
parent::__construct($it);
}
...and then change the instantiation to:
foreach(new DirectoryFilterIterator(new DirectoryIterator('.')) as $key => $value) {
echo "$key -> $value\n";
}
Finally I found this solution, hope someone finds it helpful. One could apply this pattern to any decorated Iterator, effectively ending up with something like a "filtered" iterator.
class FilteredIterator implements \Iterator
{
protected $currentProcessed = null;
protected $key = -1; // Keys are maintained by the decorating class
public function __construct(Iterator $iterator)
{
$this->it = $iterator;
}
// Iterator interface START -->
public function rewind() {
$this->it->rewind();
$this->forward();
}
public function current() {
return $this->currentProcessed;
}
public function key() {
return $this->key;
}
public function next() {
$this->it->next();
$this->forward();
}
public function valid() {
return $this->it->valid();
}
// <-- Iterator interface END
protected function forward() : void
{
if(!$this->it->valid()) {
// Stop when iterator is done
return;
}
// Pseudo code, insert expensive processing function here -->
$content = $this->it->current();
if($content === 5) {
// <-- Pseudo code END
// Skip
$this->next();
return;
}
// Update position
$this->key++;
// Cache successfully processed step
$this->currentProcessed = $content;
}
}
$arrayObject = new ArrayObject([1,2,3,4,5,6]);
$filteredIterator = new FilteredIterator($arrayObject->getIterator());
foreach ($filteredIterator as $key => $value) {
echo $key . ' -> ' . $value . "\n";
}
//0 -> 1
//1 -> 2
//2 -> 3
//3 -> 4
//4 -> 6

Php: turning it into a recursive function

I have currently two classes.
the ArrayCompare class:
<?php
namespace App\Tools\RegexExtract;
class ArrayCompare
{
public function compare(Array $arrayToCompare)
{
$elementData = new ElementMetaData();
$metaData = $elementData->extract($arrayToCompare[0], [], $initial=true);
foreach ($arrayToCompare as $currentElement) {
$metaData = $elementData->extract($currentElement, $metaData);
}
return $metaData;
}
}
which uses the ElementMetaData class
<?php
/**
* A class for extracting meta data from an element.
*/
namespace App\Tools\RegexExtract;
class ElementMetaData
{
public function extract($element, $metaDataToCompare = [], $initial = false)
{
if ($initial == true) {
$this->isInteger($element) ? $returnMetaData['isInteger'] = $this->isInteger($element) : null;
$returnMetaData['length'] = $this->length($element);
}
else {
$returnMetaData=$metaDataToCompare;
if ($returnMetaData != []) {
if (isset ($returnMetaData['isInteger']) && !$this->isInteger($element)) {
unset($returnMetaData['isInteger']);
}
if (isset ($returnMetaData['length']) && $this->length($element) != $returnMetaData['length']) {
unset($returnMetaData['length']);
}
}
}
return $returnMetaData;
}
private function isInteger($element)
{
return is_int($element);
}
private function length($element)
{
return strlen($element);
}
}
the basic functionality is:
given I have an array
$arr=[1,2,3];
I want to get the "similarities" between ALL Elements. According to a an array i Predefine...so this would deliver this result:
$metaArray=['isInteger'=>true,'length'=>1];
and this would deliver just length as similarity:
$arr=[1,2,'D'];
$metaArray=['length'=>1];
While this array would deliver an empty result []
$arr=[1,2,'3D']; // result is [] since not all integers or not all of same length.
Now my solution does not use recursive functions...but I am sure it can be used somehow.
Also, I want to add more "criteria"....So "isEmailAdress", "beginswithA"....etc....and this would make my if statements a horror....so what is the best strategy/design pattern to follow here?
#deceze beat me to it by fair margin... but I'll still post my solution that works basically with the same principles.
abstract class abstractComparer
{
private $array;
private $result = true;
protected $name;
public function compareArray($array)
{
$current = null;
foreach ($array as $index => $value)
{
$this->result = $this->result && $this->compareValues($index, $current, $value);
$current = $value;
}
}
public function getResult()
{
return $this->result;
}
public function getName()
{
return $this->name;
}
public abstract function compareValues($index, $value1, $value2);
public abstract function getSuccessValue();
}
class intComparer extends abstractComparer
{
protected $name = "isInteger";
public function compareValues($index, $value1, $value2)
{
return is_int($value2);
}
public function getSuccessValue()
{
return true;
}
}
class lengthComparer extends abstractComparer
{
protected $name = "length";
protected $length = 0;
public function compareValues($index, $value1, $value2)
{
$this->length = strlen($value2);
return $index == 0 || strlen($value1) == $this->length;
}
public function getSuccessValue()
{
return $this->length;
}
}
And do the actual processing like this:
$temp = [1,2,3];
$comparers = [new intComparer(), new lengthComparer()];
$result = array();
foreach ($comparers as $comparer)
{
$comparer->compareArray($temp);
if ($comparer->getResult())
{
$result[$comparer->getName()] = $comparer->getSuccessValue();
}
}
//var_dump($result);
I don't see any need for recursion here, so I'll just make a suggestion for a design approach:
Implement each criterion as a class:
abstract class Criterion {
protected $valid = true;
abstract public function initialize($value);
abstract public function check($value);
public function isValid() {
return $this->valid;
}
}
class Length extends Criterion {
protected $length;
public function initialize($value) {
$this->length = strlen($value);
}
public function check($value) {
if ($this->length != strlen($value)) {
$this->valid = false;
}
}
}
You then make an array of all your criteria:
$criteria = [new Length, ...];
foreach ($criteria as $criterion) {
$criterion->initialize($values[0]);
}
And slowly whittle them down through your values:
foreach ($values as $value) {
foreach ($criteria as $criterion) {
$criterion->check($value);
}
}
$commonCriteria = array_filter($criteria, function (Criterion $criterion) {
return $criterion->isValid();
});

How to make a calculator in PHP?

I want to use PHP to calculate simple algebraic expressions like, 8*(5+1), entered via an <input> tag by a normal user (which means, normal notation: no syntax changes like Multiply(8, Add(5, 1))). Also, it has to show all steps, but that's not hard. The problem, right now, is calculating the value of the expressions.
Note: this is what I thought so far, which is quite inefficient but it's a provisory solution.
Just replace strings where possible: in our example, recognize the string 5+1 and replace it with 6. Then, loop again, replace (6) with 6, loop again, and replace 8*6 with 48.
The code for multiplying, for example, should look like this:
for ($a=1; $a < 1000; $a++) {
for ($b=1; $b < 1000; $b++) {
string_replace($a . '*' . $b, $a*$b, $string);
}
}
Depending on your needs, I would suggest looking into the Shunting Yard Algorithm. It's pretty easy to implement, and works quite well.
Here's an example I whipped up a while ago: GIST.
Here's the code copy/pasted into one block:
Expression Definitions:
class Parenthesis extends TerminalExpression {
protected $precidence = 7;
public function operate(Stack $stack) {
}
public function getPrecidence() {
return $this->precidence;
}
public function isNoOp() {
return true;
}
public function isParenthesis() {
return true;
}
public function isOpen() {
return $this->value == '(';
}
}
class Number extends TerminalExpression {
public function operate(Stack $stack) {
return $this->value;
}
}
abstract class Operator extends TerminalExpression {
protected $precidence = 0;
protected $leftAssoc = true;
public function getPrecidence() {
return $this->precidence;
}
public function isLeftAssoc() {
return $this->leftAssoc;
}
public function isOperator() {
return true;
}
}
class Addition extends Operator {
protected $precidence = 4;
public function operate(Stack $stack) {
return $stack->pop()->operate($stack) + $stack->pop()->operate($stack);
}
}
class Subtraction extends Operator {
protected $precidence = 4;
public function operate(Stack $stack) {
$left = $stack->pop()->operate($stack);
$right = $stack->pop()->operate($stack);
return $right - $left;
}
}
class Multiplication extends Operator {
protected $precidence = 5;
public function operate(Stack $stack) {
return $stack->pop()->operate($stack) * $stack->pop()->operate($stack);
}
}
class Division extends Operator {
protected $precidence = 5;
public function operate(Stack $stack) {
$left = $stack->pop()->operate($stack);
$right = $stack->pop()->operate($stack);
return $right / $left;
}
}
class Power extends Operator {
protected $precidence=6;
public function operate(Stack $stack) {
$left = $stack->pop()->operate($stack);
$right = $stack->pop()->operate($stack);
return pow($right, $left);
}
}
abstract class TerminalExpression {
protected $value = '';
public function __construct($value) {
$this->value = $value;
}
public static function factory($value) {
if (is_object($value) && $value instanceof TerminalExpression) {
return $value;
} elseif (is_numeric($value)) {
return new Number($value);
} elseif ($value == '+') {
return new Addition($value);
} elseif ($value == '-') {
return new Subtraction($value);
} elseif ($value == '*') {
return new Multiplication($value);
} elseif ($value == '/') {
return new Division($value);
} elseif ($value == '^') {
return new Power($value);
} elseif (in_array($value, array('(', ')'))) {
return new Parenthesis($value);
}
throw new Exception('Undefined Value ' . $value);
}
abstract public function operate(Stack $stack);
public function isOperator() {
return false;
}
public function isParenthesis() {
return false;
}
public function isNoOp() {
return false;
}
public function render() {
return $this->value;
}
}
The stack (really simple implementation):
class Stack {
protected $data = array();
public function push($element) {
$this->data[] = $element;
}
public function poke() {
return end($this->data);
}
public function pop() {
return array_pop($this->data);
}
}
And finally, the executor class:
class Math {
protected $variables = array();
public function evaluate($string) {
$stack = $this->parse($string);
return $this->run($stack);
}
public function parse($string) {
$tokens = $this->tokenize($string);
$output = new Stack();
$operators = new Stack();
foreach ($tokens as $token) {
$token = $this->extractVariables($token);
$expression = TerminalExpression::factory($token);
if ($expression->isOperator()) {
$this->parseOperator($expression, $output, $operators);
} elseif ($expression->isParenthesis()) {
$this->parseParenthesis($expression, $output, $operators);
} else {
$output->push($expression);
}
}
while (($op = $operators->pop())) {
if ($op->isParenthesis()) {
throw new RuntimeException('Mismatched Parenthesis');
}
$output->push($op);
}
return $output;
}
public function registerVariable($name, $value) {
$this->variables[$name] = $value;
}
public function run(Stack $stack) {
while (($operator = $stack->pop()) && $operator->isOperator()) {
$value = $operator->operate($stack);
if (!is_null($value)) {
$stack->push(TerminalExpression::factory($value));
}
}
return $operator ? $operator->render() : $this->render($stack);
}
protected function extractVariables($token) {
if ($token[0] == '$') {
$key = substr($token, 1);
return isset($this->variables[$key]) ? $this->variables[$key] : 0;
}
return $token;
}
protected function render(Stack $stack) {
$output = '';
while (($el = $stack->pop())) {
$output .= $el->render();
}
if ($output) {
return $output;
}
throw new RuntimeException('Could not render output');
}
protected function parseParenthesis(TerminalExpression $expression, Stack $output, Stack $operators) {
if ($expression->isOpen()) {
$operators->push($expression);
} else {
$clean = false;
while (($end = $operators->pop())) {
if ($end->isParenthesis()) {
$clean = true;
break;
} else {
$output->push($end);
}
}
if (!$clean) {
throw new RuntimeException('Mismatched Parenthesis');
}
}
}
protected function parseOperator(TerminalExpression $expression, Stack $output, Stack $operators) {
$end = $operators->poke();
if (!$end) {
$operators->push($expression);
} elseif ($end->isOperator()) {
do {
if ($expression->isLeftAssoc() && $expression->getPrecidence() <= $end->getPrecidence()) {
$output->push($operators->pop());
} elseif (!$expression->isLeftAssoc() && $expression->getPrecidence() < $end->getPrecidence()) {
$output->push($operators->pop());
} else {
break;
}
} while (($end = $operators->poke()) && $end->isOperator());
$operators->push($expression);
} else {
$operators->push($expression);
}
}
protected function tokenize($string) {
$parts = preg_split('((\d+|\+|-|\(|\)|\*|/)|\s+)', $string, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$parts = array_map('trim', $parts);
return $parts;
}
}
It works by first tokenizing the input (based on word boundary, and tokens). Then, it runs the Shunting Yard algorithm on it to convert the input into a RPN (Reverse Polish Notation) stack. Then, it's just a matter of executing the stack. Here's a quick example:
$math = new Math();
$answer = $math->evaluate('(2 + 3) * 4');
var_dump($answer);
// int(20)
$answer = $math->evaluate('1 + 2 * ((3 + 4) * 5 + 6)');
var_dump($answer);
// int(83)
$answer = $math->evaluate('(1 + 2) * (3 + 4) * (5 + 6)');
var_dump($answer);
// int(231)
$math->registerVariable('a', 4);
$answer = $math->evaluate('($a + 3) * 4');
var_dump($answer);
// int(28)
$math->registerVariable('a', 5);
$answer = $math->evaluate('($a + $a) * 4');
var_dump($answer);
// int(40)
Now, this example is significantly more complex than you may need. The reason is that it also handles grouping and operator precedence. But it's a decent example of a running algorithm that doesn't use EVAL and supports variables...
There is a Math Parser class called bcParserPHP that might be of interest.
Seems fairly simple to use and pretty powerful.
Example code from their site:
$parser = new MathParser();
$parser->setVariable('X', 5);
$parser->setVariable('Y', 2);
$parser->setExpression('COS(X)+SIN(Y)/2');
echo $parser->getValue();
Unfortunately, it's a commercial product; I don't know if that would stop you using it or not (guess it depends on the price and on your needs).
A non-commercial alternative might be this one: http://www.phpclasses.org/package/2695-PHP-Safely-evaluate-mathematical-expressions.html
Note that this class uses eval() internally, which I would avoid doing if possible.
Failing that, writing your own language parser would be the ideal solution, but not really sensible to do that in PHP.
I'd start by stripping the input of anything which shouldn't be in the expression (assuming you just want to allow add, subtract, multiply, divide, and no variables):
$expr = preg_replace('/[^0-9+*\/-]/', '', $expr);
and then, once I'm confident nothing dangerous remains in the user input, simply pass the itthrough eval() to evaluate the expression:
$result = eval("return $expr;");
No need to reinvent the wheel.
Edited to incorporate Kolink's corrections. Thanks!

Best way to do multiple constructors in PHP

You can't put two __construct functions with unique argument signatures in a PHP class. I'd like to do this:
class Student
{
protected $id;
protected $name;
// etc.
public function __construct($id){
$this->id = $id;
// other members are still uninitialized
}
public function __construct($row_from_database){
$this->id = $row_from_database->id;
$this->name = $row_from_database->name;
// etc.
}
}
What is the best way to do this in PHP?
I'd probably do something like this:
<?php
class Student
{
public function __construct() {
// allocate your stuff
}
public static function withID( $id ) {
$instance = new self();
$instance->loadByID( $id );
return $instance;
}
public static function withRow( array $row ) {
$instance = new self();
$instance->fill( $row );
return $instance;
}
protected function loadByID( $id ) {
// do query
$row = my_awesome_db_access_stuff( $id );
$this->fill( $row );
}
protected function fill( array $row ) {
// fill all properties from array
}
}
?>
Then if i want a Student where i know the ID:
$student = Student::withID( $id );
Or if i have an array of the db row:
$student = Student::withRow( $row );
Technically you're not building multiple constructors, just static helper methods, but you get to avoid a lot of spaghetti code in the constructor this way.
The solution of Kris is really nice, but I prefer a mix of factory and fluent style:
<?php
class Student
{
protected $firstName;
protected $lastName;
// etc.
/**
* Constructor
*/
public function __construct() {
// allocate your stuff
}
/**
* Static constructor / factory
*/
public static function create() {
return new self();
}
/**
* FirstName setter - fluent style
*/
public function setFirstName($firstName) {
$this->firstName = $firstName;
return $this;
}
/**
* LastName setter - fluent style
*/
public function setLastName($lastName) {
$this->lastName = $lastName;
return $this;
}
}
// create instance
$student= Student::create()->setFirstName("John")->setLastName("Doe");
// see result
var_dump($student);
?>
PHP is a dynamic language, so you can't overload methods. You have to check the types of your argument like this:
class Student
{
protected $id;
protected $name;
// etc.
public function __construct($idOrRow){
if(is_int($idOrRow))
{
$this->id = $idOrRow;
// other members are still uninitialized
}
else if(is_array($idOrRow))
{
$this->id = $idOrRow->id;
$this->name = $idOrRow->name;
// etc.
}
}
As has already been shown here, there are many ways of declaring multiple constructors in PHP, but none of them are the correct way of doing so (since PHP technically doesn't allow it).
But it doesn't stop us from hacking this functionality...
Here's another example:
<?php
class myClass {
public function __construct() {
$get_arguments = func_get_args();
$number_of_arguments = func_num_args();
if (method_exists($this, $method_name = '__construct'.$number_of_arguments)) {
call_user_func_array(array($this, $method_name), $get_arguments);
}
}
public function __construct1($argument1) {
echo 'constructor with 1 parameter ' . $argument1 . "\n";
}
public function __construct2($argument1, $argument2) {
echo 'constructor with 2 parameter ' . $argument1 . ' ' . $argument2 . "\n";
}
public function __construct3($argument1, $argument2, $argument3) {
echo 'constructor with 3 parameter ' . $argument1 . ' ' . $argument2 . ' ' . $argument3 . "\n";
}
}
$object1 = new myClass('BUET');
$object2 = new myClass('BUET', 'is');
$object3 = new myClass('BUET', 'is', 'Best.');
Source: The easiest way to use and understand multiple constructors:
Hope this helps. :)
public function __construct() {
$parameters = func_get_args();
...
}
$o = new MyClass('One', 'Two', 3);
Now $paramters will be an array with the values 'One', 'Two', 3.
Edit,
I can add that
func_num_args()
will give you the number of parameters to the function.
You could do something like this:
public function __construct($param)
{
if(is_int($param)) {
$this->id = $param;
} elseif(is_object($param)) {
// do something else
}
}
As of version 5.4, PHP supports traits. This is not exactly what you are looking for, but a simplistic trait based approach would be:
trait StudentTrait {
protected $id;
protected $name;
final public function setId($id) {
$this->id = $id;
return $this;
}
final public function getId() { return $this->id; }
final public function setName($name) {
$this->name = $name;
return $this;
}
final public function getName() { return $this->name; }
}
class Student1 {
use StudentTrait;
final public function __construct($id) { $this->setId($id); }
}
class Student2 {
use StudentTrait;
final public function __construct($id, $name) { $this->setId($id)->setName($name); }
}
We end up with two classes, one for each constructor, which is a bit counter-productive. To maintain some sanity, I'll throw in a factory:
class StudentFactory {
static public function getStudent($id, $name = null) {
return
is_null($name)
? new Student1($id)
: new Student2($id, $name)
}
}
So, it all comes down to this:
$student1 = StudentFactory::getStudent(1);
$student2 = StudentFactory::getStudent(1, "yannis");
It's a horribly verbose approach, but it can be extremely convenient.
Here is an elegant way to do it. Create trait that will enable multiple constructors given the number of parameters. You would simply add the number of parameters to the function name "__construct". So one parameter will be "__construct1", two "__construct2"... etc.
trait constructable
{
public function __construct()
{
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array([$this,$f],$a);
}
}
}
class a{
use constructable;
public $result;
public function __construct1($a){
$this->result = $a;
}
public function __construct2($a, $b){
$this->result = $a + $b;
}
}
echo (new a(1))->result; // 1
echo (new a(1,2))->result; // 3
Another option is to use default arguments in the constructor like this
class Student {
private $id;
private $name;
//...
public function __construct($id, $row=array()) {
$this->id = $id;
foreach($row as $key => $value) $this->$key = $value;
}
}
This means you'll need to instantiate with a row like this: $student = new Student($row['id'], $row) but keeps your constructor nice and clean.
On the other hand, if you want to make use of polymorphism then you can create two classes like so:
class Student {
public function __construct($row) {
foreach($row as $key => $value) $this->$key = $value;
}
}
class EmptyStudent extends Student {
public function __construct($id) {
parent::__construct(array('id' => $id));
}
}
as stated in the other comments, as php does not support overloading, usually the "type checking tricks" in constructor are avoided and the factory pattern is used intead
ie.
$myObj = MyClass::factory('fromInteger', $params);
$myObj = MyClass::factory('fromRow', $params);
You could do something like the following which is really easy and very clean:
public function __construct()
{
$arguments = func_get_args();
switch(sizeof(func_get_args()))
{
case 0: //No arguments
break;
case 1: //One argument
$this->do_something($arguments[0]);
break;
case 2: //Two arguments
$this->do_something_else($arguments[0], $arguments[1]);
break;
}
}
This question has already been answered with very smart ways to fulfil the requirement but I am wondering why not take a step back and ask the basic question of why do we need a class with two constructors?
If my class needs two constructors then probably the way I am designing my classes needs little more consideration to come up with a design that is cleaner and more testable.
We are trying to mix up how to instantiate a class with the actual class logic.
If a Student object is in a valid state, then does it matter if it was constructed from the row of a DB or data from a web form or a cli request?
Now to answer the question that that may arise here that if we don't add the logic of creating an object from db row, then how do we create an object from the db data, we can simply add another class, call it StudentMapper if you are comfortable with data mapper pattern, in some cases you can use StudentRepository, and if nothing fits your needs you can make a StudentFactory to handle all kinds of object construction tasks.
Bottomline is to keep persistence layer out of our head when we are working on the domain objects.
I know I'm super late to the party here, but I came up with a fairly flexible pattern that should allow some really interesting and versatile implementations.
Set up your class as you normally would, with whatever variables you like.
class MyClass{
protected $myVar1;
protected $myVar2;
public function __construct($obj = null){
if($obj){
foreach (((object)$obj) as $key => $value) {
if(isset($value) && in_array($key, array_keys(get_object_vars($this)))){
$this->$key = $value;
}
}
}
}
}
When you make your object just pass an associative array with the keys of the array the same as the names of your vars, like so...
$sample_variable = new MyClass([
'myVar2'=>123,
'i_dont_want_this_one'=> 'This won\'t make it into the class'
]);
print_r($sample_variable);
The print_r($sample_variable); after this instantiation yields the following:
MyClass Object ( [myVar1:protected] => [myVar2:protected] => 123 )
Because we've initialize $group to null in our __construct(...), it is also valid to pass nothing whatsoever into the constructor as well, like so...
$sample_variable = new MyClass();
print_r($sample_variable);
Now the output is exactly as expected:
MyClass Object ( [myVar1:protected] => [myVar2:protected] => )
The reason I wrote this was so that I could directly pass the output of json_decode(...) to my constructor, and not worry about it too much.
This was executed in PHP 7.1. Enjoy!
I was facing the same issue on creating multiple constructors with different signatures but unfortunately, PHP doesn't offer a direct method to do so. Howerever, I found a trick to overcome that. Hope works for all of you too.
<?PHP
class Animal
{
public function __construct()
{
$arguments = func_get_args();
$numberOfArguments = func_num_args();
if (method_exists($this, $function = '__construct'.$numberOfArguments)) {
call_user_func_array(array($this, $function), $arguments);
}
}
public function __construct1($a1)
{
echo('__construct with 1 param called: '.$a1.PHP_EOL);
}
public function __construct2($a1, $a2)
{
echo('__construct with 2 params called: '.$a1.','.$a2.PHP_EOL);
}
public function __construct3($a1, $a2, $a3)
{
echo('__construct with 3 params called: '.$a1.','.$a2.','.$a3.PHP_EOL);
}
}
$o = new Animal('sheep');
$o = new Animal('sheep','cat');
$o = new Animal('sheep','cat','dog');
// __construct with 1 param called: sheep
// __construct with 2 params called: sheep,cat
// __construct with 3 params called: sheep,cat,dog
This is my take on it (build for php 5.6).
It will look at constructor parameter types (array, class name, no description) and compare the given arguments. Constructors must be given with least specificity last. With examples:
// demo class
class X {
public $X;
public function __construct($x) {
$this->X = $x;
}
public function __toString() {
return 'X'.$this->X;
}
}
// demo class
class Y {
public $Y;
public function __construct($y) {
$this->Y = $y;
}
public function __toString() {
return 'Y'.$this->Y;
}
}
// here be magic
abstract class MultipleConstructors {
function __construct() {
$__get_arguments = func_get_args();
$__number_of_arguments = func_num_args();
$__reflect = new ReflectionClass($this);
foreach($__reflect->getMethods() as $__reflectmethod) {
$__method_name = $__reflectmethod->getName();
if (substr($__method_name, 0, strlen('__construct')) === '__construct') {
$__parms = $__reflectmethod->getParameters();
if (count($__parms) == $__number_of_arguments) {
$__argsFit = true;
foreach ($__parms as $__argPos => $__param) {
$__paramClass= $__param->getClass();
$__argVar = func_get_arg($__argPos);
$__argVarType = gettype($__argVar);
$__paramIsArray = $__param->isArray() == true;
$__argVarIsArray = $__argVarType == 'array';
// parameter is array and argument isn't, or the other way around.
if (($__paramIsArray && !$__argVarIsArray) ||
(!$__paramIsArray && $__argVarIsArray)) {
$__argsFit = false;
continue;
}
// class check
if ((!is_null($__paramClass) && $__argVarType != 'object') ||
(is_null($__paramClass) && $__argVarType == 'object')){
$__argsFit = false;
continue;
}
if (!is_null($__paramClass) && $__argVarType == 'object') {
// class type check
$__paramClassName = "N/A";
if ($__paramClass)
$__paramClassName = $__paramClass->getName();
if ($__paramClassName != get_class($__argVar)) {
$__argsFit = false;
}
}
}
if ($__argsFit) {
call_user_func_array(array($this, $__method_name), $__get_arguments);
return;
}
}
}
}
throw new Exception("No matching constructors");
}
}
// how to use multiple constructors
class A extends MultipleConstructors {
public $value;
function __constructB(array $hey) {
$this->value = 'Array#'.count($hey).'<br/>';
}
function __construct1(X $first) {
$this->value = $first .'<br/>';
}
function __construct2(Y $second) {
$this->value = $second .'<br/>';
}
function __constructA($hey) {
$this->value = $hey.'<br/>';
}
function __toString() {
return $this->value;
}
}
$x = new X("foo");
$y = new Y("bar");
$aa = new A(array("one", "two", "three"));
echo $aa;
$ar = new A("baz");
echo $ar;
$ax = new A($x);
echo $ax;
$ay = new A($y);
echo $ay;
Result:
Array#3
baz
Xfoo
Ybar
Instead of the terminating exception if no constructor is found, it could be remove and allow for "empty" constructor. Or whatever you like.
Let me add my grain of sand here
I personally like adding a constructors as static functions that return an instance of the class (the object). The following code is an example:
class Person
{
private $name;
private $email;
public static function withName($name)
{
$person = new Person();
$person->name = $name;
return $person;
}
public static function withEmail($email)
{
$person = new Person();
$person->email = $email;
return $person;
}
}
Note that now you can create instance of the Person class like this:
$person1 = Person::withName('Example');
$person2 = Person::withEmail('yo#mi_email.com');
I took that code from:
http://alfonsojimenez.com/post/30377422731/multiple-constructors-in-php
Hmm, surprised I don't see this answer yet, suppose I'll throw my hat in the ring.
class Action {
const cancelable = 0;
const target = 1
const type = 2;
public $cancelable;
public $target;
public $type;
__construct( $opt = [] ){
$this->cancelable = isset($opt[cancelable]) ? $opt[cancelable] : true;
$this->target = isset($opt[target]) ? $opt[target] : NULL;
$this->type = isset($opt[type]) ? $opt[type] : 'action';
}
}
$myAction = new Action( [
Action::cancelable => false,
Action::type => 'spin',
.
.
.
]);
You can optionally separate the options into their own class, such as extending SplEnum.
abstract class ActionOpt extends SplEnum{
const cancelable = 0;
const target = 1
const type = 2;
}
Starting with PHP 8 we can use named arguments:
class Student {
protected int $id;
protected string $name;
public function __construct(int $id = null, string $name = null, array $row_from_database = null) {
if ($id !== null && $name !== null && $row_from_database === null) {
$this->id = $id;
$this->name = $name;
} elseif ($id === null && $name === null
&& $row_from_database !== null
&& array_keys($row_from_database) === [ 'id', 'name' ]
&& is_int($row_from_database['id'])
&& is_string($row_from_database['name'])) {
$this->id = $row_from_database['id'];
$this->name = $row_from_database['name'];
} else {
throw new InvalidArgumentException('Invalid arguments');
}
}
}
$student1 = new Student(id: 3, name: 'abc');
$student2 = new Student(row_from_database: [ 'id' => 4, 'name' => 'def' ]);
With proper checking it is possible to rule out invalid combinations of arguments, so that the created instance is a valid one at the end of the constructor (but errors will only be detected at runtime).
For php7, I compare parameters type as well, you can have two constructors with same number of parameters but different type.
trait GenericConstructorOverloadTrait
{
/**
* #var array Constructors metadata
*/
private static $constructorsCache;
/**
* Generic constructor
* GenericConstructorOverloadTrait constructor.
*/
public function __construct()
{
$params = func_get_args();
$numParams = func_num_args();
$finish = false;
if(!self::$constructorsCache){
$class = new \ReflectionClass($this);
$constructors = array_filter($class->getMethods(),
function (\ReflectionMethod $method) {
return preg_match("/\_\_construct[0-9]+/",$method->getName());
});
self::$constructorsCache = $constructors;
}
else{
$constructors = self::$constructorsCache;
}
foreach($constructors as $constructor){
$reflectionParams = $constructor->getParameters();
if(count($reflectionParams) != $numParams){
continue;
}
$matched = true;
for($i=0; $i< $numParams; $i++){
if($reflectionParams[$i]->hasType()){
$type = $reflectionParams[$i]->getType()->__toString();
}
if(
!(
!$reflectionParams[$i]->hasType() ||
($reflectionParams[$i]->hasType() &&
is_object($params[$i]) &&
$params[$i] instanceof $type) ||
($reflectionParams[$i]->hasType() &&
$reflectionParams[$i]->getType()->__toString() ==
gettype($params[$i]))
)
) {
$matched = false;
break;
}
}
if($matched){
call_user_func_array(array($this,$constructor->getName()),
$params);
$finish = true;
break;
}
}
unset($constructor);
if(!$finish){
throw new \InvalidArgumentException("Cannot match construct by params");
}
}
}
To use it:
class MultiConstructorClass{
use GenericConstructorOverloadTrait;
private $param1;
private $param2;
private $param3;
public function __construct1($param1, array $param2)
{
$this->param1 = $param1;
$this->param2 = $param2;
}
public function __construct2($param1, array $param2, \DateTime $param3)
{
$this->__construct1($param1, $param2);
$this->param3 = $param3;
}
/**
* #return \DateTime
*/
public function getParam3()
{
return $this->param3;
}
/**
* #return array
*/
public function getParam2()
{
return $this->param2;
}
/**
* #return mixed
*/
public function getParam1()
{
return $this->param1;
}
}
More modern aproach:
You are mixing seperate classes into one, entity & data hydration.
So for your case you should have 2 classes:
class Student
{
protected $id;
protected $name;
// etc.
}
class StudentHydrator
{
public function hydrate(Student $student, array $data){
$student->setId($data['id']);
if(isset($data['name')){
$student->setName($data['name']);
}
// etc. Can be replaced with foreach
return $student;
}
}
//usage
$hydrator = new StudentHydrator();
$student = $hydrator->hydrate(new Student(), ['id'=>4]);
$student2 = $hydrator->hydrate(new Student(), $rowFromDB);
Also please note that you should use doctrine or other ORM that already provides automatic entity hydration.
And you should use dependency injection in order to skip mannualy creating objects like StudentHydrator.
Kris's answer is great, but as Buttle Butku commented, new static() would be preferred in PHP 5.3+.
So I'd do it like this (modified from Kris's answer):
<?php
class Student
{
public function __construct() {
// allocate your stuff
}
public static function withID( $id ) {
$instance = new static();
$instance->loadByID( $id );
return $instance;
}
public static function withRow( array $row ) {
$instance = new static();
$instance->fill( $row );
return $instance;
}
protected function loadByID( $id ) {
// do query
$row = my_awesome_db_access_stuff( $id );
$this->fill( $row );
}
protected function fill( array $row ) {
// fill all properties from array
}
}
?>
Usage:
<?php
$student1 = Student::withID($id);
$student2 = Student::withRow($row);
?>
I also found an useful example in php.net OOP document.
In response to the best answer by Kris (which amazingly helped design my own class btw), here is a modified version for those that might find it useful. Includes methods for selecting from any column and dumping object data from array. Cheers!
public function __construct() {
$this -> id = 0;
//...
}
public static function Exists($id) {
if (!$id) return false;
$id = (int)$id;
if ($id <= 0) return false;
$mysqli = Mysql::Connect();
if (mysqli_num_rows(mysqli_query($mysqli, "SELECT id FROM users WHERE id = " . $id)) == 1) return true;
return false;
}
public static function FromId($id) {
$u = new self();
if (!$u -> FillFromColumn("id", $id)) return false;
return $u;
}
public static function FromColumn($column, $value) {
$u = new self();
if (!$u -> FillFromColumn($column, $value)) return false;
return $u;
}
public static function FromArray($row = array()) {
if (!is_array($row) || $row == array()) return false;
$u = new self();
$u -> FillFromArray($row);
return $u;
}
protected function FillFromColumn($column, $value) {
$mysqli = Mysql::Connect();
//Assuming we're only allowed to specified EXISTENT columns
$result = mysqli_query($mysqli, "SELECT * FROM users WHERE " . $column . " = '" . $value . "'");
$count = mysqli_num_rows($result);
if ($count == 0) return false;
$row = mysqli_fetch_assoc($result);
$this -> FillFromArray($row);
}
protected function FillFromArray(array $row) {
foreach($row as $i => $v) {
if (isset($this -> $i)) {
$this -> $i = $v;
}
}
}
public function ToArray() {
$m = array();
foreach ($this as $i => $v) {
$m[$i] = $v;
}
return $m;
}
public function Dump() {
print_r("<PRE>");
print_r($this -> ToArray());
print_r("</PRE>");
}
Call constructors by data type:
class A
{
function __construct($argument)
{
$type = gettype($argument);
if($type == 'unknown type')
{
// type unknown
}
$this->{'__construct_'.$type}($argument);
}
function __construct_boolean($argument)
{
// do something
}
function __construct_integer($argument)
{
// do something
}
function __construct_double($argument)
{
// do something
}
function __construct_string($argument)
{
// do something
}
function __construct_array($argument)
{
// do something
}
function __construct_object($argument)
{
// do something
}
function __construct_resource($argument)
{
// do something
}
// other functions
}
You could always add an extra parameter to the constructor called something like mode and then perform a switch statement on it...
class myClass
{
var $error ;
function __construct ( $data, $mode )
{
$this->error = false
switch ( $mode )
{
'id' : processId ( $data ) ; break ;
'row' : processRow ( $data ); break ;
default : $this->error = true ; break ;
}
}
function processId ( $data ) { /* code */ }
function processRow ( $data ) { /* code */ }
}
$a = new myClass ( $data, 'id' ) ;
$b = new myClass ( $data, 'row' ) ;
$c = new myClass ( $data, 'something' ) ;
if ( $a->error )
exit ( 'invalid mode' ) ;
if ( $b->error )
exit ('invalid mode' ) ;
if ( $c->error )
exit ('invalid mode' ) ;
Also with that method at any time if you wanted to add more functionality you can just add another case to the switch statement, and you can also check to make sure someone has sent the right thing through - in the above example all the data is ok except for C as that is set to "something" and so the error flag in the class is set and control is returned back to the main program for it to decide what to do next (in the example I just told it to exit with an error message "invalid mode" - but alternatively you could loop it back round until valid data is found).
I created this method to let use it not only on constructors but in methods:
My constructor:
function __construct() {
$paramsNumber=func_num_args();
if($paramsNumber==0){
//do something
}else{
$this->overload('__construct',func_get_args());
}
}
My doSomething method:
public function doSomething() {
$paramsNumber=func_num_args();
if($paramsNumber==0){
//do something
}else{
$this->overload('doSomething',func_get_args());
}
}
Both works with this simple method:
public function overloadMethod($methodName,$params){
$paramsNumber=sizeof($params);
//methodName1(), methodName2()...
$methodNameNumber =$methodName.$paramsNumber;
if (method_exists($this,$methodNameNumber)) {
call_user_func_array(array($this,$methodNameNumber),$params);
}
}
So you can declare
__construct1($arg1), __construct2($arg1,$arg2)...
or
methodName1($arg1), methodName2($arg1,$arg2)...
and so on :)
And when using:
$myObject = new MyClass($arg1, $arg2,..., $argN);
it will call __constructN, where you defined N args
then
$myObject -> doSomething($arg1, $arg2,..., $argM)
it will call doSomethingM, , where you defined M args;

Categories