Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ composer.lock
clover.xml
junit-logfile.xml
tmp/
.php-version
.vscode/

# Agents
.agents/
Expand Down
3 changes: 3 additions & 0 deletions extension/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
vendor/
composer.lock
build/
70 changes: 70 additions & 0 deletions extension/array_diff_multidimensional.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

use native_types;

function array_diff_multidimensional(array $array1, mixed $array2, bool $strict = true): array {

Check warning on line 5 in extension/array_diff_multidimensional.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename function "array_diff_multidimensional" to match the regular expression ^[a-z][a-zA-Z0-9]*$.

See more on https://sonarcloud.io/project/issues?id=rogervila_array-diff-multidimensional&issues=AaBrxlYwAcua2XrYgSya&open=AaBrxlYwAcua2XrYgSya&pullRequest=71

Check failure on line 5 in extension/array_diff_multidimensional.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 47 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=rogervila_array-diff-multidimensional&issues=AaBrxlYwAcua2XrYgSyb&open=AaBrxlYwAcua2XrYgSyb&pullRequest=71
if (!is_array($array2)) {
return $array1;
}

if (count($array1) === 0 || $array1 === $array2) {

Check warning on line 10 in extension/array_diff_multidimensional.php

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use empty() to check whether the array is empty or not.

See more on https://sonarcloud.io/project/issues?id=rogervila_array-diff-multidimensional&issues=AaBrxlYwAcua2XrYgSyc&open=AaBrxlYwAcua2XrYgSyc&pullRequest=71
return [];
}

$result = [];
$epsilon = defined('PHP_FLOAT_EPSILON') ? PHP_FLOAT_EPSILON : 2.2204460492503E-16;

foreach ($array1 as $key => $value) {
// Use isset for better performance, fall back to array_key_exists for null values
if (!isset($array2[$key]) && !array_key_exists($key, $array2)) {
$result[$key] = $value;
continue;
}

$value2 = $array2[$key];

if (is_array($value)) {
if (empty($value)) {
if (!is_array($value2) || !empty($value2)) {
$result[$key] = $value;
}
continue;
}

// Only recurse if both are arrays
if (is_array($value2)) {
$recursiveArrayDiff = array_diff_multidimensional($value, $value2, $strict);
if (!empty($recursiveArrayDiff)) {
$result[$key] = $recursiveArrayDiff;
}
} else {
$result[$key] = $value;
}
continue;
}

// Handle scalar value comparison optimization
if ($strict) {
// Strict comparison - optimize float handling
if (is_float($value) && is_float($value2)) {
// Use epsilon comparison for float precision
if (abs($value - $value2) > $epsilon) {
$result[$key] = $value;
}
} elseif ($value !== $value2) {
$result[$key] = $value;
}
} else {
// Loose comparison - convert if either is float
if (is_float($value) || is_float($value2)) {
if ((string) $value != (string) $value2) {
$result[$key] = $value;
}
} elseif ($value != $value2) {
$result[$key] = $value;
}
}
}

return $result;
}
6 changes: 6 additions & 0 deletions extension/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"require-dev": {
"php": "^8.5",
"swoole/typephp": "^0.7.0"
}
}
74 changes: 74 additions & 0 deletions extension/project.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Output file path (equivalent to -o/--output)
output: build/array_diff_multidimensional

# If you only need to specify the artifact name, you can also use name
# name does not change the output directory
# name: myapp

# Build mode: bin (executable) / lib (dynamic library) / ext (PHP extension)
# Under WASM, you can also use library to generate a Component with a WIT export interface
mode: ext

# Optimization level, parallel jobs, and debug switch
optimize: 2
job: 8
debug: false

# Source list (files or directories)
sources:
- array_diff_multidimensional.php

# Ignored files or directories
ignore:
- tests/
- vendor/

# Build directory (relative paths are resolved relative to the directory containing this YAML file)
build-dir: build/out

# C++ standard version
cxx-std: c++20

# Target CPU / cross-compilation platform
march: native
# target-platform: x86_64-unknown-linux-gnu

# WASI 0.2 output: only component or browser is allowed
# wasm: component
# wasm-browser-dir: generated
# library mode can configure the WIT identifier
# wasm-package: app:calculator@1.0.0
# wasm-world: calculator

# Custom C++ compiler (gcc/g++/clang/clang++, etc.)
cpp-compiler: clang++

# Additional C++ compilation options
cxx-flags:
- -fvisibility=hidden
- -Wno-unused-parameter

# Additional linker options
ld-flags:
- -lcurl
- -lssl

# Additional C++ header search paths (equivalent to -I)
include-paths:
- /opt/mylib/include
- ../shared/headers

# Preprocessor macro definitions (equivalent to -D)
defines:
- ENABLE_LOGGING=1
- DEBUG_LEVEL=3

# Runtime / build behavior
sanitize: address
profile: false
no-literal-strings: false
no-progress: true
no-console: false
dry: false
lto: true
format: true
Loading