3v4l.org

run code in 300+ PHP versions simultaneously
<?php #CreatedBy;Aaron;11OCT2014;Odin-Framework class bolt_html { var $num_instances = 0; #This is an HTML form that allows you to update/edit database data. See options for their explination of what they do. function form($fields=NULL,$opts=NULL) { global $odin; $this->num_instances++; $instance = (isset($opts["instance"])?$opts["instance"]:"inst-".$this->num_instances); $o = array( "set_element" => "fieldset", #the "set" element, defaulted to <fieldset>. "set_class" => "", #string of all classes you want to put on each set element "wrap_element" => "ul", #the wrapping element, defaulted to <ul> "item_element" => "li", #each item's element, defaulted to <li> "new_set_on" => array(), #an array(field,..) of field names, when the code finds one of them, it will start a new set #with that field as the first element in the new set. "legends" => array(), #an array(string,..) of all legends to use. once the array ends, any remaining sets will be left with no legend #use a null value or blank string to skip fieldsets, if you need to "submit_text" => "Submit", #text of the submit button "instance" => $instance, #a unique instance (per page load) used in the field's name field to group them together #This auto-incriments if left blank. #If you leave it blank be careful to not change the number of forms called between each pageload "field_types" => array(), #an array(field=>select,field=>texarea) of field types (select, textarea, etc-). #This defaults to a type of "text" if unset for any fields "field_opts" => array(), #any field options (select <options>, or a checkbox/radio groups options) "hide_fields" => array(), #an array(field,..) of fields to hide (they will still be in your $_REQUEST ($_POST+$_GET) vars "headings" => array(), #an array(field=>string,..) of headings with "form_attrs" => array( #an array(attr=>value,..) of all form attributes "id" => $instance, #gives the form an id of its $instance "method" => "post", #post by default "action" => preg_split("/[\?]+/",$_SERVER["REQUEST_URI"],2)[0], #by default, use the current url, exlucing any $_GET variables. ), ); if($opts) { $o = $odin->array->ow_merge_r($o,$opts); } #if fields were not passed, return false if(!$fields) { return FALSE; } #create the dom object & elements $dom = new DOMDocument(); $form = $dom->createElement("form"); if(!empty($o["form_attrs"])) { foreach($o["form_attrs"] as $attr=>$value) { $form_attr = $dom->createAttribute($attr); $form_attr->value = $value; $form->appendChild($form_attr); } } #setup the elements (field)set & wrapper $set = $dom->createElement($o["set_element"]); $set_attr = $dom->createAttribute("class"); $set_count = 1; $set_attr->value = "elements set-".$set_count.(!empty($o["set_class"])?" $o[set_class]":FALSE); $set->appendChild($set_attr); if($o["legends"]) { $legend = $dom->createElement("legend",htmlentities(is_array($o["legends"])?array_shift($o["legends"]):$o["legends"])); $set->appendChild($legend); } $wrapper = $dom->createElement($o["wrap_element"]); $set->appendChild($wrapper); #append the submit button into this form, nested inside of its own div.buttons wrapper. $submit_wrap = $dom->createElement("div"); $attr = $dom->createAttribute("class"); $attr->value = "buttons"; $submit_wrap->appendChild($attr); $submit = $dom->createElement("button", htmlentities($o["submit_text"])); $submit_attr = $dom->createAttribute("type"); $submit_attr->value = "submit"; $submit->appendChild($submit_attr); $hidden_wrap = $dom->createElement($o["wrap_element"]); $attr = $dom->createAttribute("style"); $attr->value = "display:none;"; $hidden_wrap->appendChild($attr); $attr = $dom->createAttribute("class"); $attr->value = "hidden-elements"; $hidden_wrap->appendChild($attr); $submit_wrap->appendChild($submit); foreach($fields as $name=>$default) { #do we want to add a new (field)set before this field? if(!empty($o["new_set_on"]) && in_array($name, $o["new_set_on"])) { $form->appendChild($set); $set = $dom->createElement($o["set_element"]); $set_attr = $dom->createAttribute("class"); $set_count++; $set_attr->value = "elements set-".$set_count.(!empty($o["set_class"])?" $o[set_class]":FALSE); $set->appendChild($set_attr); if($o["legends"]) { $legend = $dom->createElement("legend",htmlentities(is_array($o["legends"])?array_shift($o["legends"]):$o["legends"])); $set->appendChild($legend); } $wrapper = $dom->createElement($o["wrap_element"]); $set->appendChild($wrapper); } #get this field's type $type = (isset($o["field_types"][$name])?$o["field_types"][$name]:"text"); #re/set this flag that says if this is one or many fields we're working with for this one "input". $multifields= FALSE; $label_last = FALSE; switch($type) { #catch-all for any field-types. default: #create a single input field $input = $dom->createElement("input"); break; #build out later case "label": case "hidden": case "disabled": break; #textareas case "textarea": $multifields = TRUE; $input = $dom->createElement("textarea",htmlentities($default)); #set a field name on the attribute $fname = $dom->createAttribute("name"); $fname->value = $instance.'['.$name.']'; $input->appendChild($fname); break; case "select": #does this input have multiple field options? if(empty($o["field_opts"][$name])) { $o["field_opts"][$name] = array(0=>"Please Select.."); } # $multifields = TRUE; #start a ul & give it a class of type-group $input = $dom->createElement("select"); $class = $dom->createAttribute("class"); $class->value = "$type-group"; $input->appendChild($class); #append name to this field $fname = $dom->createAttribute("name"); $fname->value = $instance.'['.$name.']'.($type=="checkbox"?"[]":FALSE); $input->appendChild($fname); #loop through all options add them to the ul foreach($o["field_opts"][$name] as $value=>$label) { $option = $dom->createElement("option",htmlentities($label)); #create the input field itself, then give it name, value, and type attributes. #field value $val = $dom->createAttribute("value"); $val->value = $value; $option->appendChild($val); #check it on if this option's value matches the field's default value. if($value==$default || (is_array($default) && in_array($value, $default))) { $checked = $dom->createAttribute("checked"); $checked->value = "checked"; $option->appendChild($checked); } $input->appendChild($option); } break; #add radio & checkboxes case "radio": case "checkbox": #does this input have multiple field options? if(!empty($o["field_opts"][$name])) { $multifields = TRUE; #start a ul & give it a class of type-group $input = $dom->createElement("ul"); $class = $dom->createAttribute("class"); $class->value = "$type-group"; $input->appendChild($class); #loop through all options add them to the ul foreach($o["field_opts"][$name] as $value=>$label) { $li = $dom->createElement("li"); #create the input field itself, then give it name, value, and type attributes. $field = $dom->createElement("input"); #field name $fname = $dom->createAttribute("name"); $fname->value = $instance.'['.$name.']'.($type=="checkbox"?"[]":FALSE); $field->appendChild($fname); #field value $val = $dom->createAttribute("value"); $val->value = $value; $field->appendChild($val); #field type $type_attr = $dom->createAttribute("type"); $type_attr->value = $type; $field->appendChild($type_attr); #check it on if this option's value matches the field's default value. if($value==$default || (is_array($default) && in_array($value, $default))) { $checked = $dom->createAttribute("checked"); $checked->value = "checked"; $field->appendChild($checked); } #create a <label> for this option $opt_label = $dom->createElement("label"); $name_span = $dom->createElement("span",htmlentities($label)); #add the input field to the label $opt_label->appendChild($field); #add the field-name (span) to the label $opt_label->appendChild($name_span); #add the label to the li $li->appendChild($opt_label); #add the li to the ul $input->appendChild($li); } } else { #This checkbox (or radio) only has one option $label_last = TRUE; #Create a single input field $input = $dom->createElement("input"); #If there is any default at all, check this field on. if(!empty($default)) { $checked = $dom->createAttribute("checked"); $checked->value = "checked"; $input->appendChild($checked); } } break; } #create the item-level wrapping element & give it appropriate classes $element = $dom->createElement($o["item_element"]); $el_class = $dom->createAttribute("class"); $el_class->value = "ft-$type f-$name"; $element->appendChild($el_class); #is this a single-field attribute? if(!$multifields) { #wrap everything in a label $label = $dom->createElement("label"); #set a field name on the attribute $fname = $dom->createAttribute("name"); $fname->value = $instance.'['.$name.']'; $input->appendChild($fname); #add the type attribute to the input field $type_attr = $dom->createAttribute("type"); $type_attr->value = $type; $input->appendChild($type_attr); #if there is a default value, set it here. if($default) { $dval = $dom->createAttribute("value"); $dval->value = $default; $input->appendChild($dval); } #create a span with the field's name in it and add that into the label tag. $name_span = $dom->createElement("span",htmlentities(isset($o["headings"][$name])?:$name)); if($label_last) { #add the input to the label $label->appendChild($input); #add the name-span to the label. $label->appendChild($name_span); } else { #add the name-span to the label. $label->appendChild($name_span); #add the input to the label $label->appendChild($input); } $element->appendChild($label); } else { /* This is a multi-field attribute, which means that $input is already done. Don't modify it or wrap a label around it or anything, just add its name span before you add it to the wrapper. Just stick it straight in!! */ $name_span = $dom->createElement("span",htmlentities($name)); if($label_last) { $element->appendChild($input); $element->appendChild($name_span); } else { $element->appendChild($name_span); $element->appendChild($input); } } if(in_array($name, $o["hide_fields"])) { $hidden_wrap->appendChild($element); } else { $wrapper->appendChild($element); } } #Add the remaining dom elements to the output $form->appendChild($set); $form->appendChild($hidden_wrap); $form->appendChild($submit_wrap); #finally, write the form tag into the dom object. Then return the dom as HTML $dom->appendChild($form); return $dom->saveHTML(); } #return a string of html that is a table. $data is the tabular data you want to load in. It can either be an array or an object. function table($data,$opts=NULL) { global $odin; $this->num_instances++; $instance = (isset($opts["instance"])?$opts["instance"]:"inst-".$this->num_instances); $o = array( "caption" => "", "skip_cols" => array(), #an array(column,..) of columns to skip "add_cols" => array(), #an array(column=>string,..) of fields to tack onto the end of this. You may use replace variables with {} #example: "hello {name}" would pull the name column for this row & replace with that value. #note: this can also overwrite previous fields too "add_replaces" => array(), #an array(variable=>string,..) which replaces into the add_cols "headings" => array(), #an array(column=>string,..) of replacement headings for each column "tbl_attrs" => array( #an array(attr=>value,..) of all table attributes "id" => $instance, ), ); if($opts) { $o = $odin->array->ow_merge_r($o,$opts); } if(!empty($o["skip_cols"])) { $o["skip_cols"] = array_flip($o["skip_cols"]); } if(!empty($o["add_cols"])) { #loop through all $data, adding in those $add_cols to the end, while running str_replace on them. $keys = array_keys(current((array)$data)); $wrap_keys = function(&$val){ $val = "{".$val."}"; }; array_walk($keys, $wrap_keys); if(!empty($o["add_replaces"])) { $ar_keys = array_keys($o["add_replaces"]); $ar_vals = array_values($o["add_replaces"]); array_walk($ar_keys, $wrap_keys); } foreach($data as &$v) { foreach($o["add_cols"] as $name=>$string) { #if the column is already set, use its value instead of $string. if(isset($v[$name])) { $string = $v[$name]; } #if there are add_replace key/values, run those first so that if they contain {field_name}s, they will be replaced too. if(isset($ar_keys)) { $string = str_replace($ar_keys, $ar_vals, $string); } #replace this row's field names with field values $v[$name] = str_replace($keys, $v, $string); } } } #create the dom object & elements $dom = new DOMDocument(); $table = $dom->createElement("table"); #add on any table attributes. if(!empty($o["tbl_attrs"])) { foreach($o["tbl_attrs"] as $attr=>$value) { $table_attr = $dom->createAttribute($attr); $table_attr->value = $value; $table->appendChild($table_attr); } } #this is the first itteration through the fields, so do headings. $first = TRUE; #create <thead> $thead = $dom->createElement("thead"); $head_tr = $dom->createElement("tr"); #set a class to the <th>'s <tr> tag. $head_class = $dom->createAttribute("class"); $head_class->value = "headings"; $head_tr->appendChild($head_class); #create <tbody> $tbody = $dom->createElement("thead"); #append children where they need to go. if(!empty($o["caption"])) { $table->appendChild($dom->createElement("caption",htmlentities($o["caption"]))); } $thead->appendChild($head_tr); $table->appendChild($thead); $table->appendChild($tbody); $row_count = 0; foreach($data as $row_key=>$columns) { $row_count++; #generate new <tr> tag & its classes $tr = $dom->createElement("tr"); $tr_classes = $dom->createAttribute("class"); $tr_classes->value = ($row_count%2?"odd":"even")." row-".$row_key; $tr->appendChild($tr_classes); foreach($columns as $name=>$value) { #skip this column? if(!isset($o["skip_cols"][$name])) { #is this the first row ever? if($first) { $th = $dom->createElement("th",htmlentities(isset($o["headings"][$name])?$o["headings"][$name]:$name)); $head_tr->appendChild($th); } #create the <th> tag & fill it with your values, as long as this value is not blank. $td = $dom->createElement("td"); if($value) { $td_val = $dom->createDocumentFragment(); if(is_array($value) || is_object($value)) { $value = json_encode((array)$value); } $value = str_replace('&', '&amp;', $value); $td_val->appendXML($value); $td->appendChild($td_val); } $td_classes = $dom->createAttribute("class"); $td_classes->value = $name; $td->appendChild($td_classes); $tr->appendChild($td); } } $tbody->appendChild($tr); $first = NULL; } $dom->appendChild($table); return $dom->saveHTML(); } }

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)
8.3.60.0090.00618.33
8.3.50.0070.01421.92
8.3.40.0070.01018.84
8.3.30.0070.00719.07
8.3.20.0000.00820.55
8.3.10.0000.00823.52
8.3.00.0040.00419.13
8.2.180.0130.00316.88
8.2.170.0130.00322.96
8.2.160.0040.01820.41
8.2.150.0040.00424.18
8.2.140.0060.00324.66
8.2.130.0040.00426.16
8.2.120.0040.00422.07
8.2.110.0090.00022.20
8.2.100.0060.00617.75
8.2.90.0040.00419.34
8.2.80.0040.00417.97
8.2.70.0060.00317.48
8.2.60.0120.00018.15
8.2.50.0030.00618.07
8.2.40.0000.00819.82
8.2.30.0030.00518.07
8.2.20.0000.00817.70
8.2.10.0040.00418.03
8.2.00.0040.00417.76
8.1.280.0110.00425.92
8.1.270.0090.00023.97
8.1.260.0050.00326.35
8.1.250.0060.00328.09
8.1.240.0070.00423.98
8.1.230.0040.00719.46
8.1.220.0000.00817.74
8.1.210.0080.00018.77
8.1.200.0030.00617.35
8.1.190.0060.00317.25
8.1.180.0000.00818.10
8.1.170.0030.00818.57
8.1.160.0050.00522.18
8.1.150.0030.00618.91
8.1.140.0080.00017.47
8.1.130.0040.00417.95
8.1.120.0000.00817.59
8.1.110.0000.00817.46
8.1.100.0080.00017.61
8.1.90.0030.00617.45
8.1.80.0040.00417.47
8.1.70.0060.00317.58
8.1.60.0000.00917.57
8.1.50.0040.00417.66
8.1.40.0030.00517.57
8.1.30.0050.00517.64
8.1.20.0040.00417.69
8.1.10.0000.00917.60
8.1.00.0030.00517.43
8.0.300.0040.00418.77
8.0.290.0060.00316.88
8.0.280.0000.00818.42
8.0.270.0060.00317.30
8.0.260.0030.00317.46
8.0.250.0070.00017.04
8.0.240.0000.00816.94
8.0.230.0030.00316.95
8.0.220.0040.00416.86
8.0.210.0030.00616.97
8.0.200.0040.00416.94
8.0.190.0030.00616.98
8.0.180.0000.00817.04
8.0.170.0080.00016.97
8.0.160.0000.00717.08
8.0.150.0000.00716.95
8.0.140.0080.00016.87
8.0.130.0000.00613.46
8.0.120.0030.00516.98
8.0.110.0050.00316.95
8.0.100.0060.00316.78
8.0.90.0040.00417.03
8.0.80.0090.00616.94
8.0.70.0040.00417.09
8.0.60.0030.00516.86
8.0.50.0000.00816.98
8.0.30.0120.00917.27
8.0.20.0120.00817.40
8.0.10.0080.00017.07
8.0.00.0110.00916.90
7.4.330.0050.00015.02
7.4.320.0000.00716.69
7.4.300.0030.00316.61
7.4.290.0000.00816.61
7.4.280.0060.00316.59
7.4.270.0050.00316.51
7.4.260.0070.00016.68
7.4.250.0020.00516.64
7.4.240.0000.00716.72
7.4.230.0000.00716.70
7.4.220.0100.00916.64
7.4.210.0190.00316.78
7.4.200.0030.00616.72
7.4.160.0080.00816.52
7.4.150.0100.01017.40
7.4.140.0130.01017.86
7.4.130.0030.01516.64
7.4.120.0090.00816.56
7.4.110.0110.00716.41
7.4.100.0060.01316.62
7.4.90.0150.00316.65
7.4.80.0160.01019.39
7.4.70.0120.00616.68
7.4.60.0070.01016.58
7.4.50.0030.00316.55
7.4.40.0040.01216.51
7.4.30.0070.01016.68
7.4.00.0090.00914.81
7.3.330.0030.00313.32
7.3.320.0000.00513.38
7.3.310.0030.00516.38
7.3.300.0050.00216.24
7.3.290.0110.00616.41
7.3.280.0070.01116.36
7.3.270.0150.00317.40
7.3.260.0090.01116.47
7.3.250.0090.00916.48
7.3.240.0130.01016.69
7.3.230.0100.01316.61
7.3.210.0130.01216.67
7.3.200.0030.01419.39
7.3.190.0110.01416.35
7.3.180.0000.01716.48
7.3.170.0130.00316.56
7.3.160.0150.00916.44
7.3.120.0070.01414.87
7.3.110.0030.01614.90
7.3.100.0030.01015.07
7.3.90.0030.01015.05
7.3.80.0060.00914.80
7.3.70.0040.00814.86
7.3.60.0060.00615.00
7.3.50.0040.01114.63
7.3.40.0070.00714.83
7.3.30.0070.00714.86
7.3.20.0030.01016.30
7.3.10.0070.00316.53
7.3.00.0070.00416.28
7.2.330.0060.01216.59
7.2.320.0170.01216.67
7.2.310.0120.00916.41
7.2.300.0110.00616.80
7.2.290.0210.00416.73
7.2.250.0130.00714.99
7.2.240.0030.01415.17
7.2.230.0060.01015.04
7.2.220.0100.00714.73
7.2.210.0070.01014.96
7.2.200.0030.01014.98
7.2.190.0030.01014.78
7.2.180.0090.00614.93
7.2.170.0080.00414.73
7.2.60.0030.01016.66
7.2.00.0050.01019.20
7.1.330.0060.00915.67
7.1.320.0030.00915.69
7.1.310.0030.01515.53
7.1.300.0100.00315.75
7.1.290.0040.01115.59
7.1.280.0070.00715.63
7.1.270.0030.00915.50
7.1.260.0060.00915.79
7.1.200.0030.01015.65
7.1.100.0000.00918.05
7.1.70.0000.01016.95
7.1.60.0090.00919.32
7.1.50.0100.01316.39
7.1.00.0030.07322.36
7.0.200.0000.01116.58
7.0.140.0000.07322.06
7.0.100.0370.08020.37
7.0.90.0470.07320.33
7.0.80.0200.06320.02
7.0.70.0200.06720.18
7.0.60.0270.08020.20
7.0.50.0370.08320.56
7.0.40.0170.08019.96
7.0.30.0130.06020.08
7.0.20.0130.07719.99
7.0.10.0000.07719.94
7.0.00.0170.07319.96
5.6.280.0130.06721.12
5.6.250.0100.07320.69
5.6.240.0170.07020.81
5.6.230.0070.08720.66
5.6.220.0070.06320.73
5.6.210.0230.06320.74
5.6.200.0170.07021.23
5.6.190.0070.09020.99
5.6.180.0070.08021.24
5.6.170.0070.08721.01
5.6.160.0030.05321.07
5.6.150.0100.08021.11
5.6.140.0130.07721.23
5.6.130.0170.07321.10
5.6.120.0070.07321.09
5.6.110.0070.08321.13
5.6.100.0100.04321.21
5.6.90.0070.08021.08
5.6.80.0070.07720.47
5.6.70.0070.08020.43
5.6.60.0030.08020.46
5.6.50.0170.07320.52
5.6.40.0100.08020.35
5.6.30.0130.07320.37
5.6.20.0100.08020.52
5.6.10.0130.07320.46
5.6.00.0100.07720.42
5.5.380.0100.07320.53
5.5.370.0070.04720.56
5.5.360.0100.07720.46
5.5.350.0000.07720.41
5.5.340.0030.08020.96
5.5.330.0100.08020.70
5.5.320.0130.08320.86
5.5.310.0070.08320.70
5.5.300.0070.08020.98
5.5.290.0130.07720.89
5.5.280.0100.08020.98
5.5.270.0070.07320.95
5.5.260.0030.08020.86
5.5.250.0070.06720.68
5.5.240.0100.07320.21
5.5.230.0070.05720.38
5.5.220.0030.09020.30
5.5.210.0170.05720.27
5.5.200.0130.07020.24
5.5.190.0030.09020.25
5.5.180.0000.09020.29
5.5.160.0100.07320.22
5.5.150.0070.07720.24
5.5.140.0030.08320.33
5.5.130.0100.08020.32
5.5.120.0070.07720.21
5.5.110.0070.07720.29
5.5.100.0030.08320.11
5.5.90.0170.06020.14
5.5.80.0070.08020.13
5.5.70.0030.05320.12
5.5.60.0100.07020.16
5.5.50.0070.07320.10
5.5.40.0070.08020.12
5.5.30.0070.07720.16
5.5.20.0070.08320.12
5.5.10.0130.07320.14
5.5.00.0000.07020.14
5.4.450.0100.08319.48
5.4.440.0070.08319.21
5.4.430.0030.08319.41
5.4.420.0070.08319.21
5.4.410.0100.07019.29
5.4.400.0100.08018.93
5.4.390.0070.07719.14
5.4.380.0030.08318.99
5.4.370.0130.06719.14
5.4.360.0000.08019.09
5.4.350.0100.07019.09
5.4.340.0130.07319.05
5.4.320.0030.07719.09
5.4.310.0070.07319.25
5.4.300.0130.07019.16
5.4.290.0030.08019.05
5.4.280.0070.07319.09
5.4.270.0070.07319.16
5.4.260.0100.07019.13
5.4.250.0070.07319.23
5.4.240.0070.04719.10
5.4.230.0100.07019.25
5.4.220.0130.06318.98
5.4.210.0000.08319.14
5.4.200.0130.06319.13
5.4.190.0200.06319.21
5.4.180.0170.06719.13
5.4.170.0170.06719.09
5.4.160.0070.08019.04
5.4.150.0030.08018.92
5.4.140.0030.07316.28
5.4.130.0100.07016.48
5.4.120.0030.07316.43
5.4.110.0030.06016.47
5.4.100.0100.07016.48
5.4.90.0070.07016.55
5.4.80.0130.06316.45
5.4.70.0030.08016.58
5.4.60.0130.07316.50
5.4.50.0070.07316.43
5.4.40.0030.07316.52
5.4.30.0100.06716.51
5.4.20.0070.07716.50
5.4.10.0070.04716.38
5.4.00.0030.03715.81

preferences:
39.44 ms | 401 KiB | 5 Q