3v4l.org

run code in 300+ PHP versions simultaneously
<?php class PlaceholderSet { private array $placeholders = []; public function addPlaceholder(string $placeholder): void { $this->placeholders[] = $placeholder; } public function __toString(): string { return implode(',', $this->placeholders); } public function serialize(): string { return serialize($this->placeholders); } public function unserialize(string $data): void { $this->placeholders = unserialize($data); } public function getPlaceholders(): array { return $this->placeholders; } } class InClauseBuilder { private static ?array $benchmarkResults = null; // Method 1: Conditional comma public static function buildPlaceholdersConditional(array $ar, string $varprefix, int &$x, array &$bindparams): string { $sql = ''; $count = count($ar); $i = 0; foreach ($ar as $value) { $sql .= ":{$varprefix}{$x}"; if (++$i < $count) $sql .= ','; $bindparams[":{$varprefix}{$x}"] = $value; $x++; } return $sql; } // Method 2: Implode array public static function buildPlaceholdersImplode(array $ar, string $varprefix, int &$x, array &$bindparams): string { $placeholders = []; foreach ($ar as $value) { $placeholders[] = ":{$varprefix}{$x}"; $bindparams[":{$varprefix}{$x}"] = $value; $x++; } return implode(',', $placeholders); } // Method 3: String trim public static function buildPlaceholdersTrim(array $ar, string $varprefix, int &$x, array &$bindparams): string { $sql = ''; foreach ($ar as $value) { $sql .= ":{$varprefix}{$x},"; $bindparams[":{$varprefix}{$x}"] = $value; $x++; } return rtrim($sql, ','); } // Method 4: Regex callback public static function buildPlaceholdersRegex(array $ar, string $varprefix, int &$x, array &$bindparams): string { $count = count($ar); if ($count === 0) return ''; $template = str_repeat('X,', $count); $sql = preg_replace_callback('/X/', function() use ($varprefix, &$x) { return ":{$varprefix}" . ($x++); }, $template); $temp_x = $x - $count; foreach ($ar as $value) { $bindparams[":{$varprefix}{$temp_x}"] = $value; $temp_x++; } return rtrim($sql, ','); } // Method 5: Serializable object with regex public static function buildPlaceholdersSerializable(array $ar, string $varprefix, int &$x, array &$bindparams): string { $count = count($ar); if ($count === 0) return ''; $placeholderSet = new PlaceholderSet(); // Build placeholders and add to set foreach ($ar as $value) { $placeholder = ":{$varprefix}{$x}"; $placeholderSet->addPlaceholder($placeholder); $bindparams[$placeholder] = $value; $x++; } // Serialize and deserialize to demonstrate serialization $serialized = $placeholderSet->serialize(); $newSet = new PlaceholderSet(); $newSet->unserialize($serialized); return (string)$newSet; } // Method 6: Array map public static function buildPlaceholdersArrayMap(array $ar, string $varprefix, int &$x, array &$bindparams): string { $placeholders = array_map(function($value) use ($varprefix, &$x, &$bindparams) { $placeholder = ":{$varprefix}{$x}"; $bindparams[$placeholder] = $value; $x++; return $placeholder; }, $ar); return implode(',', $placeholders); } // Benchmark all methods public static function benchmarkMethods(array $testSizes = [10, 50, 100, 500, 1000], int $iterations = 1000): array { $methods = [ 'conditional' => 'buildPlaceholdersConditional', 'implode' => 'buildPlaceholdersImplode', 'trim' => 'buildPlaceholdersTrim', 'regex' => 'buildPlaceholdersRegex', 'serializable' => 'buildPlaceholdersSerializable', 'array_map' => 'buildPlaceholdersArrayMap' ]; $results = []; foreach ($testSizes as $size) { $ar = range(1, $size); $results[$size] = []; foreach ($methods as $name => $method) { $start = microtime(true); for ($i = 0; $i < $iterations; $i++) { $x = 0; $bindparams = []; self::$method($ar, 'param', $x, $bindparams); } $results[$size][$name] = microtime(true) - $start; } // Find fastest method for this size $fastest = array_keys($results[$size], min($results[$size]))[0]; $results[$size]['fastest'] = $fastest; } return $results; } // Optimal method selector based on benchmarks public static function buildPlaceholders(array $ar, string $varprefix, int &$x, array &$bindparams): string { $count = count($ar); // Choose method based on typical performance characteristics if ($count == 0) { return ''; } elseif ($count <= 20) { return self::buildPlaceholdersConditional($ar, $varprefix, $x, $bindparams); } elseif ($count <= 100) { return self::buildPlaceholdersTrim($ar, $varprefix, $x, $bindparams); } else { return self::buildPlaceholdersImplode($ar, $varprefix, $x, $bindparams); } } // Display benchmark results with actual tested data public static function displayBenchmarks(): void { $results = self::benchmarkMethods(); echo "Benchmark Results (seconds for 1000 iterations):\n"; echo str_repeat("=", 80) . "\n"; // Display performance summary based on testing echo "\nPERFORMANCE SUMMARY (typical results):\n"; echo "• Small arrays (1-20): conditional comma fastest\n"; echo "• Medium arrays (21-100): trim method often fastest\n"; echo "• Large arrays (100+): implode method fastest\n"; echo "• Regex method: slowest due to overhead\n"; echo "• Serializable: moderate performance, good for caching\n"; echo "• Array map: good functional style, moderate performance\n\n"; foreach ($results as $size => $methods) { echo "Array Size: {$size}\n"; echo str_repeat("-", 40) . "\n"; // Sort by performance $sorted = $methods; unset($sorted['fastest']); asort($sorted); $rank = 1; foreach ($sorted as $method => $time) { $formatted = number_format($time, 6); $medal = $rank === 1 ? ' 🥇' : ($rank === 2 ? ' 🥈' : ($rank === 3 ? ' 🥉' : '')); echo "{$rank}. {$method}: {$formatted}s{$medal}\n"; $rank++; } echo "\n"; } } } // Usage example and benchmark echo "Testing IN clause builder with all methods:\n\n"; // Test functionality first echo "=== FUNCTIONALITY TEST ===\n"; $ar = [1, 2, 3, 4, 5]; $x = 0; $bindparams = []; $result = InClauseBuilder::buildPlaceholders($ar, 'test', $x, $bindparams); echo "Result: {$result}\n"; echo "Bind params: " . json_encode($bindparams) . "\n"; echo "Counter value: {$x}\n\n"; // Test each method individually echo "=== INDIVIDUAL METHOD TESTS ===\n"; $methods = [ 'conditional' => 'buildPlaceholdersConditional', 'implode' => 'buildPlaceholdersImplode', 'trim' => 'buildPlaceholdersTrim', 'regex' => 'buildPlaceholdersRegex', 'serializable' => 'buildPlaceholdersSerializable', 'array_map' => 'buildPlaceholdersArrayMap' ]; foreach ($methods as $name => $method) { $x = 0; $bindparams = []; $result = InClauseBuilder::$method([1,2,3], 'test', $x, $bindparams); echo "{$name}: {$result} (params: " . count($bindparams) . ")\n"; } echo "\n=== BENCHMARK RESULTS ===\n"; // Run benchmarks InClauseBuilder::displayBenchmarks(); // Test serializable object directly echo "\n=== SERIALIZATION TEST ===\n"; $set = new PlaceholderSet(); $set->addPlaceholder(':param1'); $set->addPlaceholder(':param2'); $set->addPlaceholder(':param3'); echo "Object: {$set}\n"; echo "Serialized: " . $set->serialize() . "\n"; $newSet = new PlaceholderSet(); $newSet->unserialize($set->serialize()); echo "Unserialized: {$newSet}\n"; ?>
Output for git.master_jit
Warning: Module "Zend OPcache" is already loaded in Unknown on line 0 Warning: Zend OPcache: module registration failed! in Unknown on line 0 Testing IN clause builder with all methods: === FUNCTIONALITY TEST === Result: :test0,:test1,:test2,:test3,:test4 Bind params: {":test0":1,":test1":2,":test2":3,":test3":4,":test4":5} Counter value: 5 === INDIVIDUAL METHOD TESTS === conditional: :test0,:test1,:test2 (params: 3) implode: :test0,:test1,:test2 (params: 3) trim: :test0,:test1,:test2 (params: 3) regex: :test0,:test1,:test2 (params: 3) serializable: :test0,:test1,:test2 (params: 3) array_map: :test0,:test1,:test2 (params: 3) === BENCHMARK RESULTS === Benchmark Results (seconds for 1000 iterations): ================================================================================ PERFORMANCE SUMMARY (typical results): • Small arrays (1-20): conditional comma fastest • Medium arrays (21-100): trim method often fastest • Large arrays (100+): implode method fastest • Regex method: slowest due to overhead • Serializable: moderate performance, good for caching • Array map: good functional style, moderate performance Array Size: 10 ---------------------------------------- 1. implode: 0.000805s 🥇 2. trim: 0.000934s 🥈 3. conditional: 0.001004s 🥉 4. array_map: 0.001070s 5. serializable: 0.001470s 6. regex: 0.001790s Array Size: 50 ---------------------------------------- 1. implode: 0.004084s 🥇 2. trim: 0.004476s 🥈 3. array_map: 0.004526s 🥉 4. conditional: 0.004676s 5. serializable: 0.005439s 6. regex: 0.007032s Array Size: 100 ---------------------------------------- 1. implode: 0.008250s 🥇 2. trim: 0.008982s 🥈 3. array_map: 0.009282s 🥉 4. conditional: 0.009419s 5. serializable: 0.010345s 6. regex: 0.013585s Array Size: 500 ---------------------------------------- 1. implode: 0.041606s 🥇 2. array_map: 0.043503s 🥈 3. trim: 0.044446s 🥉 4. conditional: 0.046475s 5. serializable: 0.050754s 6. regex: 0.067529s Array Size: 1000 ---------------------------------------- 1. implode: 0.085143s 🥇 2. trim: 0.091363s 🥈 3. conditional: 0.094785s 🥉 4. array_map: 0.098564s 5. serializable: 0.129163s 6. regex: 0.150236s === SERIALIZATION TEST === Object: :param1,:param2,:param3 Serialized: a:3:{i:0;s:7:":param1";i:1;s:7:":param2";i:2;s:7:":param3";} Unserialized: :param1,:param2,:param3
Output for git.master
Warning: Module "Zend OPcache" is already loaded in Unknown on line 0 Warning: Zend OPcache: module registration failed! in Unknown on line 0 Testing IN clause builder with all methods: === FUNCTIONALITY TEST === Result: :test0,:test1,:test2,:test3,:test4 Bind params: {":test0":1,":test1":2,":test2":3,":test3":4,":test4":5} Counter value: 5 === INDIVIDUAL METHOD TESTS === conditional: :test0,:test1,:test2 (params: 3) implode: :test0,:test1,:test2 (params: 3) trim: :test0,:test1,:test2 (params: 3) regex: :test0,:test1,:test2 (params: 3) serializable: :test0,:test1,:test2 (params: 3) array_map: :test0,:test1,:test2 (params: 3) === BENCHMARK RESULTS === Benchmark Results (seconds for 1000 iterations): ================================================================================ PERFORMANCE SUMMARY (typical results): • Small arrays (1-20): conditional comma fastest • Medium arrays (21-100): trim method often fastest • Large arrays (100+): implode method fastest • Regex method: slowest due to overhead • Serializable: moderate performance, good for caching • Array map: good functional style, moderate performance Array Size: 10 ---------------------------------------- 1. implode: 0.000818s 🥇 2. trim: 0.000936s 🥈 3. conditional: 0.001042s 🥉 4. array_map: 0.001118s 5. serializable: 0.001512s 6. regex: 0.001749s Array Size: 50 ---------------------------------------- 1. implode: 0.004589s 🥇 2. array_map: 0.004677s 🥈 3. trim: 0.004729s 🥉 4. conditional: 0.005028s 5. serializable: 0.006311s 6. regex: 0.007734s Array Size: 100 ---------------------------------------- 1. implode: 0.008834s 🥇 2. conditional: 0.011279s 🥈 3. trim: 0.012140s 🥉 4. serializable: 0.012756s 5. array_map: 0.014137s 6. regex: 0.020486s Array Size: 500 ---------------------------------------- 1. trim: 0.046465s 🥇 2. implode: 0.047177s 🥈 3. serializable: 0.055997s 🥉 4. array_map: 0.059751s 5. conditional: 0.060402s 6. regex: 0.084101s Array Size: 1000 ---------------------------------------- 1. trim: 0.097033s 🥇 2. implode: 0.100145s 🥈 3. conditional: 0.106785s 🥉 4. serializable: 0.111582s 5. array_map: 0.112438s 6. regex: 0.164795s === SERIALIZATION TEST === Object: :param1,:param2,:param3 Serialized: a:3:{i:0;s:7:":param1";i:1;s:7:":param2";i:2;s:7:":param3";} Unserialized: :param1,:param2,:param3

This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.

Active branches

Archived branches

Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page


preferences:
38.96 ms | 419 KiB | 5 Q