3v4l.org

run code in 300+ PHP versions simultaneously
<?php /** * SETTINGS. * * Objects of class Settings are injected to factories * as initiators of various classes. * * Process: * - FUNCTIONS.PHP: Create object Settings(). * - FUNCTIONS.PHP: Set args by Settings:set(). * - FUNCTIONS.PHP: Create object Factory($settings). * - CLASS-FACTORY.PHP: Create functionality objects according to settings. * - CLASS-WORKER.PHP: Parent functionality. * * @author Petr Cibulka <cibulka.me@gmail.com> * @link http://cibulka.me * * @package Cibulka_Framework\Architecture * @since 1.0 * @version 1.0 * * @filesource */ // ---------------------------------------------------------------------------------- /** * SETTINGS CLASS. * * @used-by Factory() * @package Cibulka_Framework\Architecture * */ // ---------------------------------------------------------------------------------- class Settings { private $prefix = ''; private $spec = []; private $workers = []; /** * CONSTRUCTOR. * * Sets prefix. The rest is done by Settings::setters(); * * @param string $prefix Sets prefix for all chained classes. * */ function __construct($prefix) { $this->prefix = $prefix; } // -------------------------------------------------------------------------- /** * SETTER. * * Note: If unique worker needed, leave ID blank * => arg TYPE will act both like type of functionality AND unique ID. * * @param string $type Sets type of functionality. If class should be unique, acts as ID as well. * @param string $id * @param array $args Args are later validated by Worker(). * */ public function set($type,$id='',$args='') { /*ID*/ $id = $this->get_id($type,$id); if (!$id) { return false; } /*SPEC*/ $spec = $this->create_spec($type,$id,$args); /*VALIDATION & TRANSLATION*/ $v = new Validator(); try { // SPEC: Validation $v->spec_validate($type); // ARGS: Translation $v->args_translate($args,$type); // ARGS: Validation $v->args_validate($args,$type); } catch (Exception $e) { $message = $e->getMessage(); $line = $e->getLine(); $file = $e->getFile(); $trace = $e->getTrace(); ?> <table> <tr> <th colspan="2"><?php echo $message; ?></th> </tr><tr> <td>Line: <?php echo $line; ?></td> <td>File: <?php echo $file; ?></td>'; </tr><tr> </tr><tr> <td colspan="2">Trace: <?php echo $trace; ?></td> </tr> </table> <?php return false; } /*ARGS*/ $this->workers[$id]['type'] = $type; $this->workers[$id]['args'] = (!empty($args)) ? $args : array(); /*TEST*/ //helper::printr($this); } // -------------------------------------------------------------------------- private function get_id($type,$id) { $id = (!empty($id)) ? $id : $type; // Error // TODO: Create proper exception if (array_key_exists($id,$this->workers)) { $text = 'Worker with ID '.$id.' already exists.'; $error = new Error($this,$text); trigger_error(); return false; } return $id; } private function create_spec($type,$id,$args) { $spec_name = ucfirst($this->prefix).'_'.ucfirst($type).'_Spec'; // Initiate, if not already if (!array_key_exists($type, $this->spec)) { $this->spec[$type] = new $spec_name($type,$id); } return $spec_name; } // -------------------------------------------------------------------------- private function spec_validate($type) { $spec = $this->spec[$type]; foreach ($spec as $spec_term => $spec_row) { // Conflicting spec keys // req & def if (array_key_exists('req',$spec_row)) {} // wrong type to check if (!empty($spec_row['type'])) { $type = helper::str_to_array($spec_row['type']); $type_supported = array('boolean','integer','double','string','array','object','resource','null','file'); $type_unsupported = array_diff($type,$type_supported); if ($type_unsupported) { trigger_error('Unsupported type!'); return false; } } // wrong count if (!empty($spec_row['count'] && is_string($spec_row['count'])) { // max & min // range } } return true; } private function args_translate($args,$type) { $spec = $this->spec[$type]; foreach ($spec as $spec_term => $spec_row) { /*KEYS & DEF values*/ $spec_def_value = (!empty($property_row['def'])) ? $property_row['def'] : null; // SET if (!empty($this->args[$spec_term])) { continue; } else { $this->args[$spec_term] = $spec_def_value; } } return true; } private function args_validate($args,$type) { $spec = $this->spec[$type]->get_all(); /*SHOULD WE VALIDATE?*/ if (!$spec) { // ARGS disabled & Not set => ok if (empty($this->args)) { return; } // ARGS disabled & set => not ok else { trigger_error('ARGS are not allowed'); } } /*UNSUPPORTED SPEC*/ $args_terms_unsupported = array_diff_key($this->args, $spec); if ($args_terms_unsupported) { trigger_error('Unsupported keys: '.implode(', ', $args_terms_unsupported)); return false; } /*LOOP THROUGH SPEC*/ foreach ($spec as $spec_term => $spec_row) { $user_value = $this->args[$spec_term]; // ERROR: Required keys missing $req = $spec_row['req']; if ($req && empty($user_value)) { trigger_error('Required ARG '.$spec_term.' is empty.'); return false; } // CONTINUE if $user_val empty if (empty($user_value)) { continue; } // ERROR: Count if (!empty($spec_row['count'])) { $user_count = count(helper::str_to_array($user_value)); $count_error = $this->user_val_count($user_count,$spec_row['count']); if ($count_error) { trigger_error('Wrong count on '.$spec_term); } } // ERROR: TYPE: File if (!empty($spec_row['type']) && !is_array($spec_row['type']) && 'file' === $spec_row['type']) { // Escape type checking later $type_escape = true; // Error: File is not a string $user_value_is_string = is_string($user_value); if (!$user_value_is_string) { trigger_error('File must be string.'); return false; } // Error: File does not exist $file_exists = $this->check_file($user_value); if (!$file_exists) { trigger_error('File has weird SRC.'); return false; } } // ERROR: TYPE: Common types if (!empty($spec_row['type'] && !$type_escape) { $user_value_type_supported = in_array(gettype($user_value),helper::str_to_array($spec_types)); if (!$user_value_type_supported) { trigger_error('Value type is not supported'); return false; } } // ERROR: VALUES if (!empty($spec_row['vals'])) { $user_val_unsupported = array_diff(helper::str_to_array($user_val),$spec_val); if ($user_val_unsupported) { trigger_error('Value is unsupported'); return false; } } } return true; } } // ------------------------------------------------------------------------------ interface Spec_Interface { public function set($property,$key,$value=''); public function get($property); } interface Spec_Interface_Child { public function spec_set(); } abstract class Spec implements Spec_Interface { protected $worker = array( 'type' => '', 'id' => '' ); // -------------------------------------------------------------------------- function __construct($type,$id) { $this->worker['type'] = $type; $this->worker['id'] = $id; /*SPEC*/ // Sets default values & allowed values if (method_exists($this,'spec_set')) { try { // parent $this->spec_set(); // child if (method_exists($this,'spec_set_child')) { $this->spec_set_child(); } } catch (Exception $e) { } } } // -------------------------------------------------------------------------- // TODO: Exceptions function set($property,$spec_key,$value='') { $allowed_keys = array('def','vals'); if (!in_array($spec_key,$allowed_keys)) { trigger_error('TYPES accepted: '.implode(', ', $allowed_keys).'. Type provided: <b>'.$spec_key.'</b>.'); } if (property_exists($this,$property)) { $this->{$property}[$spec_key] = $value; } else { trigger_error('Property <b>'.$spec_key.'</b> is not supported.'); } } function get($property) { if (property_exists($this,$property)) { return $this->{$property}; } else { trigger_error('Property '.$property.' does not exist.'); } } function get_all() { return get_object_vars($this); } } abstract class Scripts_Spec extends Spec implements Spec_Interface_Child { protected $script_type = array( 'req' => true, 'num' => 1, 'vals' => array('wp','admin','login') ); protected $load = array( 'req' => false, 'num' => 1, 'type' => array('string','object'), 'vals' => array('post_edit') ); protected $autoload = array( 'req' => false, 'num' => 1, 'type' => 'boolean', 'def' => false ); protected $local = array( 'req' => false, 'num' => 1, 'type' => 'boolean', 'def' => true ); protected $id = array( 'req' => false, 'num' => 1, 'type' => 'string', 'def' => '' ); protected $src = array( 'req' => false, 'num' => 1, 'type' => 'string' ); protected $deps = array( 'req' => false, 'num' => '', 'type' => array('string','array') ); protected $ver = array( 'req' => false, 'num' => 1, 'type' => 'string' ); function spec_set() { // ID > Def: id of worker $this->set('id','def',$this->worker['id']); } } class Scripts_Js_Spec extends Scripts_Spec { } class Scripts_Css_Spec extends Scripts_Spec { } ?>

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
5.4.270.0030.05718.66
5.4.260.0200.05718.88
5.4.250.0100.05318.77
5.4.240.0200.04318.96
5.4.230.0200.06718.76
5.4.220.0170.07318.98
5.4.210.0170.05318.96
5.4.200.0130.08018.74
5.4.190.0130.07319.02
5.4.180.0130.04718.88
5.4.170.0170.06018.88
5.4.160.0230.03718.92
5.4.150.0070.07718.64
5.4.140.0000.07316.52
5.4.130.0000.06016.46
5.4.120.0030.05316.58
5.4.110.0170.05716.50
5.4.100.0130.05316.39
5.4.90.0100.05316.57
5.4.80.0030.07316.47
5.4.70.0100.05316.50
5.4.60.0200.06016.40
5.4.50.0100.05016.45
5.4.40.0130.05716.41
5.4.30.0100.05716.45
5.4.20.0100.06716.36
5.4.10.0030.06016.50
5.4.00.0130.04715.77
5.3.280.0230.05314.58
5.3.270.0170.06014.50
5.3.260.0170.06014.57
5.3.250.0070.07714.73
5.3.240.0070.06014.45
5.3.230.0070.05014.78
5.3.220.0170.04314.63
5.3.210.0200.07014.47
5.3.200.0070.05314.66
5.3.190.0070.05014.54
5.3.180.0130.06014.53
5.3.170.0130.05714.63
5.3.160.0170.04314.73
5.3.150.0100.05314.78
5.3.140.0070.06014.68
5.3.130.0100.07314.61
5.3.120.0200.05714.51
5.3.110.0070.05314.63
5.3.100.0200.05014.12
5.3.90.0070.05014.09
5.3.80.0100.05713.84
5.3.70.0170.04314.24
5.3.60.0170.05014.17
5.3.50.0030.06013.77
5.3.40.0130.06014.01
5.3.30.0100.05014.12
5.3.20.0100.04713.66
5.3.10.0100.04313.73
5.3.00.0170.04013.71
5.2.170.0070.04010.97
5.2.160.0100.03311.23
5.2.150.0170.04711.32
5.2.140.0070.05711.23
5.2.130.0170.05311.32
5.2.120.0070.04711.11
5.2.110.0030.06011.12
5.2.100.0070.03711.27
5.2.90.0000.06711.16
5.2.80.0100.05711.16
5.2.70.0100.04011.25
5.2.60.0100.04311.13
5.2.50.0170.03011.18
5.2.40.0100.04710.83
5.2.30.0030.04311.06
5.2.20.0070.04010.86
5.2.10.0000.05711.03
5.2.00.0070.04710.79
5.1.60.0070.03010.00
5.1.50.0070.0479.99
5.1.40.0100.0439.89
5.1.30.0030.03710.41
5.1.20.0100.04710.57
5.1.10.0100.03010.27
5.1.00.0130.03710.07
5.0.50.0130.0338.61
5.0.40.0030.0338.51
5.0.30.0030.0538.32
5.0.20.0100.0308.20
5.0.10.0100.0308.23
5.0.00.0000.0477.95
4.4.90.0070.0277.25
4.4.80.0130.0177.25
4.4.70.0030.0207.25
4.4.60.0030.0207.25
4.4.50.0030.0237.25
4.4.40.0030.0377.25
4.4.30.0070.0237.25
4.4.20.0070.0207.25
4.4.10.0030.0307.24
4.4.00.0070.0377.24
4.3.110.0070.0237.24
4.3.100.0070.0207.24
4.3.90.0070.0177.24
4.3.80.0000.0377.24
4.3.70.0000.0307.24
4.3.60.0000.0307.24
4.3.50.0000.0277.24
4.3.40.0070.0407.24
4.3.30.0030.0277.24
4.3.20.0100.0207.24
4.3.10.0030.0307.24
4.3.00.0070.0306.99

preferences:
140.87 ms | 1394 KiB | 7 Q