php-networking
PHP Networking, Regex & Parallel Execution
cURL & HTTP Requests
Basic Request
$ch = curl_init('https://api.example.com/data');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Accept: application/json', 'Authorization: Bearer ' . $token],
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_SSL_VERIFYPEER => true, // NEVER disable in production
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch);
if ($response === false) {
throw new RuntimeException(curl_error($ch), curl_errno($ch));
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// curl_close() optional in PHP 8+ (garbage collected)
POST / PUT / JSON
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
// Custom method (PUT, PATCH, DELETE)
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
Multi-cURL (Parallel Requests)
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $key => $url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
curl_multi_add_handle($mh, $ch);
$handles[$key] = $ch;
}
// Run all in parallel
do {
$status = curl_multi_exec($mh, $running);
if ($running) { curl_multi_select($mh); } // block until I/O ready
} while ($running > 0);
// Collect results
$results = [];
foreach ($handles as $key => $ch) {
$results[$key] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
cURL Reference
| Option | Purpose |
|---|---|
CURLOPT_RETURNTRANSFER |
Return body as string (not print) |
CURLOPT_TIMEOUT |
Total operation timeout (seconds) |
CURLOPT_CONNECTTIMEOUT |
Connection phase timeout |
CURLOPT_FOLLOWLOCATION |
Auto-follow redirects |
CURLOPT_MAXREDIRS |
Max redirects to follow |
CURLOPT_USERPWD |
Basic auth "user:pass" |
CURLOPT_ACCEPT_ENCODING |
Enable gzip/deflate (auto-decompressed) |
CURLOPT_SSL_VERIFYPEER |
Verify server certificate (default true) |
CURLOPT_SSL_VERIFYHOST |
Verify hostname in cert (use 2) |
CURLOPT_HTTPHEADER |
Custom request headers array |
CURLOPT_POSTFIELDS |
POST data (string or array) |
CurlHandle (PHP 8.0+) |
Opaque final class, replaces resource type |
| Rule | Detail |
|---|---|
| Always set timeouts | Prevent hanging on slow servers |
| Never disable SSL verification | Except in dev/test |
Use === for curl_exec() check |
Returns false on failure, not falsy |
| HTTP 4xx/5xx is not curl failure | Check CURLINFO_HTTP_CODE separately |
| Multi-curl for parallel | Much faster than sequential for multiple URLs |
Regular Expressions (PCRE)
Key Functions
// Match — returns 1 (match), 0 (no match), false (error)
preg_match('/^[a-z]+$/i', $input, $matches);
// Match all — returns count of matches
preg_match_all('/\d+/', $text, $matches);
// Replace — string or callback
$clean = preg_replace('/\s+/', ' ', $text);
$result = preg_replace_callback('/\{(\w+)\}/', fn($m) => $vars[$m[1]] ?? '', $template);
// Split
$parts = preg_split('/[\s,]+/', $csv);
// Always check for errors
if (preg_last_error() !== PREG_NO_ERROR) {
throw new RuntimeException(preg_last_error_msg());
}
Modifiers
| Modifier | Effect |
|---|---|
i |
Case-insensitive |
m |
^/$ match line boundaries (not just string start/end) |
s |
. matches newlines |
x |
Ignore whitespace + # comments in pattern |
u |
UTF-8 mode — required for multibyte strings |
U |
Invert greediness (all quantifiers ungreedy by default) |
n |
Only named groups (?<name>) capture (PHP 8.2+) |
D |
$ matches only absolute end, not before final \n |
A |
Anchor to string start |
Named Captures & Assertions
// Named captures — cleaner than $matches[1]
preg_match('/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/', $date, $m);
echo $m['year']; // "2024"
// Lookahead/lookbehind (zero-width assertions)
'/(?<=\$)\d+/' // Positive lookbehind: digits after $
'/\d+(?= USD)/' // Positive lookahead: digits before " USD"
'/foo(?!bar)/' // Negative lookahead: "foo" not followed by "bar"
ReDoS Prevention & Performance
| Rule | Detail |
|---|---|
| Avoid nested quantifiers | (a+)*, (a*)+ cause exponential backtracking |
Use atomic groups (?>...) |
Prevent backtracking into group |
| Character classes over alternation | [aeiou] faster than (a|e|i|o|u) |
| Anchor patterns | ^pattern / \Apattern fastest |
Check preg_last_error() |
Detect PREG_BACKTRACK_LIMIT_ERROR |
pcre.backtrack_limit |
Default 1M — may hit on large subjects |
| Lookbehind must be fixed-length | Variable-length lookbehind not supported |
Parallel & Async Patterns
Process Control (pcntl)
$pid = pcntl_fork();
if ($pid === -1) {
throw new RuntimeException('Fork failed');
} elseif ($pid > 0) {
// Parent — wait for child to prevent zombies
pcntl_wait($status);
} else {
// Child (pid === 0)
doWork();
exit(0);
}
Non-Blocking I/O with stream_select
stream_set_blocking($stream, false);
$read = [$stream1, $stream2, $stream3];
$write = $except = [];
// Block up to 200ms waiting for any stream to be ready
if (stream_select($read, $write, $except, 0, 200000) > 0) {
foreach ($read as $ready) {
$data = fread($ready, 8192);
}
}
parallel Extension (Modern Async)
$runtime = new parallel\Runtime();
$futures = [];
foreach ($tasks as $i => $task) {
$futures[$i] = $runtime->run(fn() => processTask($task), [$task]);
}
// Collect results (blocks if not ready)
foreach ($futures as $i => $future) {
$results[$i] = $future->value();
}
$runtime->close();
Comparison
| Approach | Best for | Notes |
|---|---|---|
curl_multi_* |
Parallel HTTP requests | Built-in, no extensions needed |
pcntl_fork() |
CPU-bound parallel work | Unix only, not thread-safe |
stream_select() |
High-concurrency I/O | Event loop pattern, thousands of connections |
parallel extension |
General async tasks | Requires ZTS PHP, message-passing model |
| Fibers (8.1+) | Cooperative concurrency | Single-thread, no true parallelism |
| Rule | Detail |
|---|---|
pcntl_fork() workers |
Match CPU count (2-4) |
stream_select() timeout |
Min 200ms to avoid CPU spin |
More from peixotorms/odinlayer-skills
elementor-development
Use when building Elementor addons, creating custom widgets, or managing Elementor components. Covers Widget_Base class (get_name, get_title, get_icon, register_controls, render, content_template), widget registration via elementor/widgets/register hook, addon structure and plugin header, wp_enqueue_script for widget assets, get_script_depends, get_style_depends, inline editing toolbars, custom widget categories, manager registration (register/unregister), selector tokens ({{WRAPPER}}), deprecation handling, and Elementor CLI commands.
65elementor-hooks
Use when hooking into Elementor lifecycle events, injecting controls, filtering widget output, or using the JS APIs. Covers elementor/init, elementor/element/before_section_end, elementor/element/after_section_end, elementor/widget/render_content filter, elementor/frontend/after_enqueue_styles, frontend JS hooks (elementorFrontend.hooks, frontend/element_ready), editor JS hooks (elementor.hooks), $e.commands API ($e.run, $e.commands.register), $e.routes, $e.hooks (registerUIBefore, registerUIAfter), control injection patterns, CSS file hooks, forms hooks (Pro), and query filters.
26elementor-themes
Use when building Elementor-compatible themes, registering theme locations, creating dynamic tags, or extending the Finder. Covers register_location, theme_builder locations, elementor_theme_do_location, Theme_Document and theme conditions, Tag_Base for dynamic tags (register_tag, get_value, render), Finder extension (Category_Base, register via elementor/finder/register), Context_Menu customization (elements/context-menu/groups filter), Hello Elementor theme (elementor-hello-theme, hello_elementor_* filters), and hosting page cache integration hooks.
25elementor-controls
Use when adding controls to Elementor widgets, creating custom controls, or referencing control type parameters. Covers add_control with types (TEXT, SELECT, SLIDER, COLOR, MEDIA, REPEATER, CHOOSE, NUMBER, SWITCHER, URL, ICONS), TYPOGRAPHY and BACKGROUND group controls, BORDER, BOX_SHADOW group controls, add_responsive_control, add_group_control, CSS selectors ({{WRAPPER}}, {{VALUE}}), condition and conditions for conditional display, dynamic content tags, POPOVER_TOGGLE, and global styles integration.
16elementor-forms
Use when creating custom Elementor form actions, custom form field types, form validation, or processing form submissions. Covers Elementor Pro forms (ElementorPro\Modules\Forms), Action_Base (get_name, get_label, run, register_settings_section, on_export), after_submit processing, Field_Base (field_type, render field HTML, validation callback, update_controls), content_template for editor preview, form action registration, export_type handling, update_record patterns, elementor_pro/forms/validation hook, email filters, and webhook response handling.
12flyonui
Use when building with FlyonUI — Tailwind CSS component library with CSS classes and optional JS plugins. Covers CSS component classes, JS plugin system (accordion, carousel, collapse, combobox, datatable, dropdown, select, tabs, tooltip, etc.), theming, installation, class reference, and plugin initialization via MCP tools.
9