Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JsArray - JavaScript Arrays in PHP

Packagist VersionPHP VersionLicenseTests

Write JavaScript Array code in PHP. Familiar, powerful, and intuitive API for working with arrays.

If you know JavaScript arrays, you already know JsArray.


What is JsArray?

JsArray brings the beloved JavaScript Array methods to PHP with:

  • Familiar API - Same methods, same behavior as JavaScript
  • Full Type Safety - PHP 8+ with complete type hints
  • Flexible - Choose immutable (safe) or mutable (fast) mode
  • Pure PHP - Zero dependencies, lightweight
  • Native PHP Interoperability - Behaves like a first-class PHP collection

Installation

composer require jsarray/jsarray

Requirements: PHP 8.0+


Quick Start

The Basics

useJsArray\JsArray;
$numbers = JsArray::from([1, 2, 3, 4, 5]);
// Transform data$doubled = $numbers->map(fn($number) => $number * 2);
// Keep only matching items$evenNumbers = $numbers->filter(fn($number) => $number % 2 === 0);
// Combine operations (method chaining)$result = $numbers
->filter(fn($number) => $number > 2)
->map(fn($number) => $number * 10)
->toArray();
// Result: [30, 40, 50]

Working with Objects

$users = JsArray::from([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 17],
['name' => 'Charlie', 'age' => 30],
]);
// Get names of adults$adultNames = $users
->filter(fn($user) => $user['age'] >= 18)
->map(fn($user) => $user['name'])
->toArray();
// Result: ['Alice', 'Charlie']

Flexible Callback Signatures

Use only the parameters you need:

// Just the item value$numbers->map(fn($number) => $number * 2);
// Item and its index$items->filter(fn($item, $index) => $index > 0);
$numbers->forEach(fn($number, $index) => echo "$index: $number");
// Full context (item, index, and array reference)$array->map(fn($item, $index, $array) =>
$item > ($array->length / 2) ? 'big' : 'small'
);

JsArray automatically detects which parameters your callback uses. No configuration needed!


Native PHP Interoperability

JsArray behaves like a first‑class PHP collection and integrates naturally with core language features.

Iteration (Iterator)

Use JsArray directly in foreach loops:

$items = JsArray::from([1, 2, 3]);
foreach ($itemsas$value) {
echo$value;
}

No conversion needed.

ArrayAccess

Use JsArray as an array:

$items = JsArray::from([1, 2, 3]);
echo$items[0]; // 1$items[0] = 10;
echo$items[0]; // 10$items->toArray(); // [10, 2, 3]

Counting (Countable)

Use PHP’s native count() function:

$items = JsArray::from([1, 2, 3]);
echocount($items); // 3

Equivalent to:

$items->length;

JSON Serialization (JsonSerializable)

Serialize JsArray cleanly using json_encode():

$items = JsArray::from([1, 2, 3]);
echojson_encode($items);

Output:

[1, 2, 3]

Create a JsArray from a JSON string:

$json = '[1, 2, 3]';
$items = JsArray::fromJson($json);
// Now you can use JsArray methods$doubled = $items->map(fn($n) => $n * 2);

This makes JsArray ideal for APIs, responses, and data transport without extra mapping.


Core Features

Transformation

$array->map(fn($item) => $item * 2); // Transform each item$array->filter(fn($item) => $item > 10); // Keep matching items$array->reduce(fn($total, $item) => $total + $item, 0); // Combine to single value$array->flat(); // Flatten nested arrays$array->flatMap(fn($item) => [$item, $item * 2]); // Map then flatten

Search

$array->find(fn($item) => $item > 100); // Get first match$array->findIndex(fn($item) => $item > 100); // Get index of first match$array->includes(50); // Check if value exists$array->indexOf(50); // Get index of value$array->some(fn($item) => $item > 100); // Check if ANY match$array->every(fn($item) => $item > 0); // Check if ALL match

Access

$array->first(); // Get first item$array->last(); // Get last item$array->at(0); // Get item at index$array->at(-1); // Get last item (negative index)$array->length; // Get array length

Manipulation

$array->push($item1, $item2); // Add items to end$array->pop(); // Remove and return last item$array->unshift($item1, $item2); // Add items to start$array->shift(); // Remove and return first item$array->slice(1, 3); // Extract portion$array->reverse(); // Reverse order$array->sort(); // Sort items$array->concat($otherArray); // Combine arrays$array->join(', '); // Join into string

Other

$array->keys(); // Get all keys$array->values(); // Get all values$array->toArray(); // Convert to native PHP array$array->forEach(fn($item) => echo $item); // Execute for each item$array->toImmutable(); // Convert array to immutable$array->toMutable(); // Convert array to mutable$array->getMutableCopy(); // Create new mutable copy of array$array->getImmutableCopy(); // Create new immutable copy of array

Two Modes: Immutable & Mutable

Immutable Mode (Default)

Creates a new array for each operation. Original is never changed.

$original = JsArray::from([1, 2, 3]);
$doubled = $original->map(fn ($n) => $n * 2);
$original->toArray(); // [1, 2, 3]$doubled->toArray(); // [2, 4, 6]

Use immutable when:

  • Processing user input
  • Data safety matters
  • Building complex logic
  • Working with small to medium arrays (< 10,000 items)

Mutable Mode (Fast)

Modifies the array in-place. Much faster for large datasets.

$array = JsArray::mutable([1, 2, 3, 4, 5]);
$array
->map(fn ($n) => $n * 2)
->filter(fn ($n) => $n > 2);
$array->toArray(); // [4, 6, 8, 10]

Use mutable when:

  • Processing large datasets (> 50,000 items)
  • Performance is critical
  • Building or accumulating data
  • Bulk operations (imports, migrations)

Converting Between Modes

Start with immutable, convert if needed

$array = JsArray::from([1, 2, 3]);
if ($arraySize > 50000) {
$array->toMutable(); // Switch to mutable mode
}

Create mutable copy without affecting original

$copy = $array->getMutableCopy();
$copy->map(...)->filter(...);
echo$array->toArray(); // Original unchanged

Convert back to immutable

$safeArray = $copy->toImmutable();

Check the mode:

$array->isMutable; // bool$array->isImmutable; // bool

Testing

Run tests:

composer test

Tests include:

  • 190+ test cases
  • All methods covered
  • Edge cases tested
  • Immutable/mutable modes tested

Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure tests pass
  5. Submit a pull request

Documentation Files


License

MIT License - See LICENSE for details.


Support


Changelog

v2.1.0

✨ Enhanced native PHP interoperability:
  • Iteration (Iterator): Seamless foreach loop support
  • ArrayAccess: Access elements using array syntax (e.g., $array[0])
  • Counting (Countable): Native count() function integration
  • JSON Serialization (JsonSerializable): Direct json_encode() support
  • JSON Deserialization: Create JsArray from JSON strings with fromJson()

v2.0.0

  • ✨ Added mutable mode for performance
  • ✨ 5 new methods (shift, unshift, indexOf, lastIndexOf, reverse)
  • ✨ Flexible callback signatures (use only params you need!)
  • ✨ Depth parameter for flat()
  • 🐛 Fixed filter re-indexing for numeric arrays
  • 📚 Comprehensive documentation files

v1.0.0

  • Initial release

JsArray - JavaScript Arrays in PHP

About

A PHP implementation of JavaScript Array methods with immutable operations and identical API behavior.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JsArray - JavaScript Arrays in PHP

Packagist VersionPHP VersionLicenseTests

Write JavaScript Array code in PHP. Familiar, powerful, and intuitive API for working with arrays.

If you know JavaScript arrays, you already know JsArray.


What is JsArray?

JsArray brings the beloved JavaScript Array methods to PHP with:

  • Familiar API - Same methods, same behavior as JavaScript
  • Full Type Safety - PHP 8+ with complete type hints
  • Flexible - Choose immutable (safe) or mutable (fast) mode
  • Pure PHP - Zero dependencies, lightweight
  • Native PHP Interoperability - Behaves like a first-class PHP collection

Installation

composer require jsarray/jsarray

Requirements: PHP 8.0+


Quick Start

The Basics

useJsArray\JsArray;
$numbers = JsArray::from([1, 2, 3, 4, 5]);
// Transform data$doubled = $numbers->map(fn($number) => $number * 2);
// Keep only matching items$evenNumbers = $numbers->filter(fn($number) => $number % 2 === 0);
// Combine operations (method chaining)$result = $numbers
->filter(fn($number) => $number > 2)
->map(fn($number) => $number * 10)
->toArray();
// Result: [30, 40, 50]

Working with Objects

$users = JsArray::from([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 17],
['name' => 'Charlie', 'age' => 30],
]);
// Get names of adults$adultNames = $users
->filter(fn($user) => $user['age'] >= 18)
->map(fn($user) => $user['name'])
->toArray();
// Result: ['Alice', 'Charlie']

Flexible Callback Signatures

Use only the parameters you need:

// Just the item value$numbers->map(fn($number) => $number * 2);
// Item and its index$items->filter(fn($item, $index) => $index > 0);
$numbers->forEach(fn($number, $index) => echo "$index: $number");
// Full context (item, index, and array reference)$array->map(fn($item, $index, $array) =>
$item > ($array->length / 2) ? 'big' : 'small'
);

JsArray automatically detects which parameters your callback uses. No configuration needed!


Native PHP Interoperability

JsArray behaves like a first‑class PHP collection and integrates naturally with core language features.

Iteration (Iterator)

Use JsArray directly in foreach loops:

$items = JsArray::from([1, 2, 3]);
foreach ($itemsas$value) {
echo$value;
}

No conversion needed.

ArrayAccess

Use JsArray as an array:

$items = JsArray::from([1, 2, 3]);
echo$items[0]; // 1$items[0] = 10;
echo$items[0]; // 10$items->toArray(); // [10, 2, 3]

Counting (Countable)

Use PHP’s native count() function:

$items = JsArray::from([1, 2, 3]);
echocount($items); // 3

Equivalent to:

$items->length;

JSON Serialization (JsonSerializable)

Serialize JsArray cleanly using json_encode():

$items = JsArray::from([1, 2, 3]);
echojson_encode($items);

Output:

[1, 2, 3]

Create a JsArray from a JSON string:

$json = '[1, 2, 3]';
$items = JsArray::fromJson($json);
// Now you can use JsArray methods$doubled = $items->map(fn($n) => $n * 2);

This makes JsArray ideal for APIs, responses, and data transport without extra mapping.


Core Features

Transformation

$array->map(fn($item) => $item * 2); // Transform each item$array->filter(fn($item) => $item > 10); // Keep matching items$array->reduce(fn($total, $item) => $total + $item, 0); // Combine to single value$array->flat(); // Flatten nested arrays$array->flatMap(fn($item) => [$item, $item * 2]); // Map then flatten

Search

$array->find(fn($item) => $item > 100); // Get first match$array->findIndex(fn($item) => $item > 100); // Get index of first match$array->includes(50); // Check if value exists$array->indexOf(50); // Get index of value$array->some(fn($item) => $item > 100); // Check if ANY match$array->every(fn($item) => $item > 0); // Check if ALL match

Access

$array->first(); // Get first item$array->last(); // Get last item$array->at(0); // Get item at index$array->at(-1); // Get last item (negative index)$array->length; // Get array length

Manipulation

$array->push($item1, $item2); // Add items to end$array->pop(); // Remove and return last item$array->unshift($item1, $item2); // Add items to start$array->shift(); // Remove and return first item$array->slice(1, 3); // Extract portion$array->reverse(); // Reverse order$array->sort(); // Sort items$array->concat($otherArray); // Combine arrays$array->join(', '); // Join into string

Other

$array->keys(); // Get all keys$array->values(); // Get all values$array->toArray(); // Convert to native PHP array$array->forEach(fn($item) => echo $item); // Execute for each item$array->toImmutable(); // Convert array to immutable$array->toMutable(); // Convert array to mutable$array->getMutableCopy(); // Create new mutable copy of array$array->getImmutableCopy(); // Create new immutable copy of array

Two Modes: Immutable & Mutable

Immutable Mode (Default)

Creates a new array for each operation. Original is never changed.

$original = JsArray::from([1, 2, 3]);
$doubled = $original->map(fn ($n) => $n * 2);
$original->toArray(); // [1, 2, 3]$doubled->toArray(); // [2, 4, 6]

Use immutable when:

  • Processing user input
  • Data safety matters
  • Building complex logic
  • Working with small to medium arrays (< 10,000 items)

Mutable Mode (Fast)

Modifies the array in-place. Much faster for large datasets.

$array = JsArray::mutable([1, 2, 3, 4, 5]);
$array
->map(fn ($n) => $n * 2)
->filter(fn ($n) => $n > 2);
$array->toArray(); // [4, 6, 8, 10]

Use mutable when:

  • Processing large datasets (> 50,000 items)
  • Performance is critical
  • Building or accumulating data
  • Bulk operations (imports, migrations)

Converting Between Modes

Start with immutable, convert if needed

$array = JsArray::from([1, 2, 3]);
if ($arraySize > 50000) {
$array->toMutable(); // Switch to mutable mode
}

Create mutable copy without affecting original

$copy = $array->getMutableCopy();
$copy->map(...)->filter(...);
echo$array->toArray(); // Original unchanged

Convert back to immutable

$safeArray = $copy->toImmutable();

Check the mode:

$array->isMutable; // bool$array->isImmutable; // bool

Testing

Run tests:

composer test

Tests include:

  • 190+ test cases
  • All methods covered
  • Edge cases tested
  • Immutable/mutable modes tested

Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure tests pass
  5. Submit a pull request

Documentation Files


License

MIT License - See LICENSE for details.


Support


Changelog

v2.1.0

✨ Enhanced native PHP interoperability:
  • Iteration (Iterator): Seamless foreach loop support
  • ArrayAccess: Access elements using array syntax (e.g., $array[0])
  • Counting (Countable): Native count() function integration
  • JSON Serialization (JsonSerializable): Direct json_encode() support
  • JSON Deserialization: Create JsArray from JSON strings with fromJson()

v2.0.0

  • ✨ Added mutable mode for performance
  • ✨ 5 new methods (shift, unshift, indexOf, lastIndexOf, reverse)
  • ✨ Flexible callback signatures (use only params you need!)
  • ✨ Depth parameter for flat()
  • 🐛 Fixed filter re-indexing for numeric arrays
  • 📚 Comprehensive documentation files

v1.0.0

  • Initial release

JsArray - JavaScript Arrays in PHP

About

A PHP implementation of JavaScript Array methods with immutable operations and identical API behavior.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JsArray - JavaScript Arrays in PHP

Packagist VersionPHP VersionLicenseTests

Write JavaScript Array code in PHP. Familiar, powerful, and intuitive API for working with arrays.

If you know JavaScript arrays, you already know JsArray.


What is JsArray?

JsArray brings the beloved JavaScript Array methods to PHP with:

  • Familiar API - Same methods, same behavior as JavaScript
  • Full Type Safety - PHP 8+ with complete type hints
  • Flexible - Choose immutable (safe) or mutable (fast) mode
  • Pure PHP - Zero dependencies, lightweight
  • Native PHP Interoperability - Behaves like a first-class PHP collection

Installation

composer require jsarray/jsarray

Requirements: PHP 8.0+


Quick Start

The Basics

useJsArray\JsArray;
$numbers = JsArray::from([1, 2, 3, 4, 5]);
// Transform data$doubled = $numbers->map(fn($number) => $number * 2);
// Keep only matching items$evenNumbers = $numbers->filter(fn($number) => $number % 2 === 0);
// Combine operations (method chaining)$result = $numbers
->filter(fn($number) => $number > 2)
->map(fn($number) => $number * 10)
->toArray();
// Result: [30, 40, 50]

Working with Objects

$users = JsArray::from([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 17],
['name' => 'Charlie', 'age' => 30],
]);
// Get names of adults$adultNames = $users
->filter(fn($user) => $user['age'] >= 18)
->map(fn($user) => $user['name'])
->toArray();
// Result: ['Alice', 'Charlie']

Flexible Callback Signatures

Use only the parameters you need:

// Just the item value$numbers->map(fn($number) => $number * 2);
// Item and its index$items->filter(fn($item, $index) => $index > 0);
$numbers->forEach(fn($number, $index) => echo "$index: $number");
// Full context (item, index, and array reference)$array->map(fn($item, $index, $array) =>
$item > ($array->length / 2) ? 'big' : 'small'
);

JsArray automatically detects which parameters your callback uses. No configuration needed!


Native PHP Interoperability

JsArray behaves like a first‑class PHP collection and integrates naturally with core language features.

Iteration (Iterator)

Use JsArray directly in foreach loops:

$items = JsArray::from([1, 2, 3]);
foreach ($itemsas$value) {
echo$value;
}

No conversion needed.

ArrayAccess

Use JsArray as an array:

$items = JsArray::from([1, 2, 3]);
echo$items[0]; // 1$items[0] = 10;
echo$items[0]; // 10$items->toArray(); // [10, 2, 3]

Counting (Countable)

Use PHP’s native count() function:

$items = JsArray::from([1, 2, 3]);
echocount($items); // 3

Equivalent to:

$items->length;

JSON Serialization (JsonSerializable)

Serialize JsArray cleanly using json_encode():

$items = JsArray::from([1, 2, 3]);
echojson_encode($items);

Output:

[1, 2, 3]

Create a JsArray from a JSON string:

$json = '[1, 2, 3]';
$items = JsArray::fromJson($json);
// Now you can use JsArray methods$doubled = $items->map(fn($n) => $n * 2);

This makes JsArray ideal for APIs, responses, and data transport without extra mapping.


Core Features

Transformation

$array->map(fn($item) => $item * 2); // Transform each item$array->filter(fn($item) => $item > 10); // Keep matching items$array->reduce(fn($total, $item) => $total + $item, 0); // Combine to single value$array->flat(); // Flatten nested arrays$array->flatMap(fn($item) => [$item, $item * 2]); // Map then flatten

Search

$array->find(fn($item) => $item > 100); // Get first match$array->findIndex(fn($item) => $item > 100); // Get index of first match$array->includes(50); // Check if value exists$array->indexOf(50); // Get index of value$array->some(fn($item) => $item > 100); // Check if ANY match$array->every(fn($item) => $item > 0); // Check if ALL match

Access

$array->first(); // Get first item$array->last(); // Get last item$array->at(0); // Get item at index$array->at(-1); // Get last item (negative index)$array->length; // Get array length

Manipulation

$array->push($item1, $item2); // Add items to end$array->pop(); // Remove and return last item$array->unshift($item1, $item2); // Add items to start$array->shift(); // Remove and return first item$array->slice(1, 3); // Extract portion$array->reverse(); // Reverse order$array->sort(); // Sort items$array->concat($otherArray); // Combine arrays$array->join(', '); // Join into string

Other

$array->keys(); // Get all keys$array->values(); // Get all values$array->toArray(); // Convert to native PHP array$array->forEach(fn($item) => echo $item); // Execute for each item$array->toImmutable(); // Convert array to immutable$array->toMutable(); // Convert array to mutable$array->getMutableCopy(); // Create new mutable copy of array$array->getImmutableCopy(); // Create new immutable copy of array

Two Modes: Immutable & Mutable

Immutable Mode (Default)

Creates a new array for each operation. Original is never changed.

$original = JsArray::from([1, 2, 3]);
$doubled = $original->map(fn ($n) => $n * 2);
$original->toArray(); // [1, 2, 3]$doubled->toArray(); // [2, 4, 6]

Use immutable when:

  • Processing user input
  • Data safety matters
  • Building complex logic
  • Working with small to medium arrays (< 10,000 items)

Mutable Mode (Fast)

Modifies the array in-place. Much faster for large datasets.

$array = JsArray::mutable([1, 2, 3, 4, 5]);
$array
->map(fn ($n) => $n * 2)
->filter(fn ($n) => $n > 2);
$array->toArray(); // [4, 6, 8, 10]

Use mutable when:

  • Processing large datasets (> 50,000 items)
  • Performance is critical
  • Building or accumulating data
  • Bulk operations (imports, migrations)

Converting Between Modes

Start with immutable, convert if needed

$array = JsArray::from([1, 2, 3]);
if ($arraySize > 50000) {
$array->toMutable(); // Switch to mutable mode
}

Create mutable copy without affecting original

$copy = $array->getMutableCopy();
$copy->map(...)->filter(...);
echo$array->toArray(); // Original unchanged

Convert back to immutable

$safeArray = $copy->toImmutable();

Check the mode:

$array->isMutable; // bool$array->isImmutable; // bool

Testing

Run tests:

composer test

Tests include:

  • 190+ test cases
  • All methods covered
  • Edge cases tested
  • Immutable/mutable modes tested

Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure tests pass
  5. Submit a pull request

Documentation Files


License

MIT License - See LICENSE for details.


Support


Changelog

v2.1.0

✨ Enhanced native PHP interoperability:
  • Iteration (Iterator): Seamless foreach loop support
  • ArrayAccess: Access elements using array syntax (e.g., $array[0])
  • Counting (Countable): Native count() function integration
  • JSON Serialization (JsonSerializable): Direct json_encode() support
  • JSON Deserialization: Create JsArray from JSON strings with fromJson()

v2.0.0

  • ✨ Added mutable mode for performance
  • ✨ 5 new methods (shift, unshift, indexOf, lastIndexOf, reverse)
  • ✨ Flexible callback signatures (use only params you need!)
  • ✨ Depth parameter for flat()
  • 🐛 Fixed filter re-indexing for numeric arrays
  • 📚 Comprehensive documentation files

v1.0.0

  • Initial release

JsArray - JavaScript Arrays in PHP

About

A PHP implementation of JavaScript Array methods with immutable operations and identical API behavior.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JsArray - JavaScript Arrays in PHP

Packagist VersionPHP VersionLicenseTests

Write JavaScript Array code in PHP. Familiar, powerful, and intuitive API for working with arrays.

If you know JavaScript arrays, you already know JsArray.


What is JsArray?

JsArray brings the beloved JavaScript Array methods to PHP with:

  • Familiar API - Same methods, same behavior as JavaScript
  • Full Type Safety - PHP 8+ with complete type hints
  • Flexible - Choose immutable (safe) or mutable (fast) mode
  • Pure PHP - Zero dependencies, lightweight
  • Native PHP Interoperability - Behaves like a first-class PHP collection

Installation

composer require jsarray/jsarray

Requirements: PHP 8.0+


Quick Start

The Basics

useJsArray\JsArray;
$numbers = JsArray::from([1, 2, 3, 4, 5]);
// Transform data$doubled = $numbers->map(fn($number) => $number * 2);
// Keep only matching items$evenNumbers = $numbers->filter(fn($number) => $number % 2 === 0);
// Combine operations (method chaining)$result = $numbers
->filter(fn($number) => $number > 2)
->map(fn($number) => $number * 10)
->toArray();
// Result: [30, 40, 50]

Working with Objects

$users = JsArray::from([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 17],
['name' => 'Charlie', 'age' => 30],
]);
// Get names of adults$adultNames = $users
->filter(fn($user) => $user['age'] >= 18)
->map(fn($user) => $user['name'])
->toArray();
// Result: ['Alice', 'Charlie']

Flexible Callback Signatures

Use only the parameters you need:

// Just the item value$numbers->map(fn($number) => $number * 2);
// Item and its index$items->filter(fn($item, $index) => $index > 0);
$numbers->forEach(fn($number, $index) => echo "$index: $number");
// Full context (item, index, and array reference)$array->map(fn($item, $index, $array) =>
$item > ($array->length / 2) ? 'big' : 'small'
);

JsArray automatically detects which parameters your callback uses. No configuration needed!


Native PHP Interoperability

JsArray behaves like a first‑class PHP collection and integrates naturally with core language features.

Iteration (Iterator)

Use JsArray directly in foreach loops:

$items = JsArray::from([1, 2, 3]);
foreach ($itemsas$value) {
echo$value;
}

No conversion needed.

ArrayAccess

Use JsArray as an array:

$items = JsArray::from([1, 2, 3]);
echo$items[0]; // 1$items[0] = 10;
echo$items[0]; // 10$items->toArray(); // [10, 2, 3]

Counting (Countable)

Use PHP’s native count() function:

$items = JsArray::from([1, 2, 3]);
echocount($items); // 3

Equivalent to:

$items->length;

JSON Serialization (JsonSerializable)

Serialize JsArray cleanly using json_encode():

$items = JsArray::from([1, 2, 3]);
echojson_encode($items);

Output:

[1, 2, 3]

Create a JsArray from a JSON string:

$json = '[1, 2, 3]';
$items = JsArray::fromJson($json);
// Now you can use JsArray methods$doubled = $items->map(fn($n) => $n * 2);

This makes JsArray ideal for APIs, responses, and data transport without extra mapping.


Core Features

Transformation

$array->map(fn($item) => $item * 2); // Transform each item$array->filter(fn($item) => $item > 10); // Keep matching items$array->reduce(fn($total, $item) => $total + $item, 0); // Combine to single value$array->flat(); // Flatten nested arrays$array->flatMap(fn($item) => [$item, $item * 2]); // Map then flatten

Search

$array->find(fn($item) => $item > 100); // Get first match$array->findIndex(fn($item) => $item > 100); // Get index of first match$array->includes(50); // Check if value exists$array->indexOf(50); // Get index of value$array->some(fn($item) => $item > 100); // Check if ANY match$array->every(fn($item) => $item > 0); // Check if ALL match

Access

$array->first(); // Get first item$array->last(); // Get last item$array->at(0); // Get item at index$array->at(-1); // Get last item (negative index)$array->length; // Get array length

Manipulation

$array->push($item1, $item2); // Add items to end$array->pop(); // Remove and return last item$array->unshift($item1, $item2); // Add items to start$array->shift(); // Remove and return first item$array->slice(1, 3); // Extract portion$array->reverse(); // Reverse order$array->sort(); // Sort items$array->concat($otherArray); // Combine arrays$array->join(', '); // Join into string

Other

$array->keys(); // Get all keys$array->values(); // Get all values$array->toArray(); // Convert to native PHP array$array->forEach(fn($item) => echo $item); // Execute for each item$array->toImmutable(); // Convert array to immutable$array->toMutable(); // Convert array to mutable$array->getMutableCopy(); // Create new mutable copy of array$array->getImmutableCopy(); // Create new immutable copy of array

Two Modes: Immutable & Mutable

Immutable Mode (Default)

Creates a new array for each operation. Original is never changed.

$original = JsArray::from([1, 2, 3]);
$doubled = $original->map(fn ($n) => $n * 2);
$original->toArray(); // [1, 2, 3]$doubled->toArray(); // [2, 4, 6]

Use immutable when:

  • Processing user input
  • Data safety matters
  • Building complex logic
  • Working with small to medium arrays (< 10,000 items)

Mutable Mode (Fast)

Modifies the array in-place. Much faster for large datasets.

$array = JsArray::mutable([1, 2, 3, 4, 5]);
$array
->map(fn ($n) => $n * 2)
->filter(fn ($n) => $n > 2);
$array->toArray(); // [4, 6, 8, 10]

Use mutable when:

  • Processing large datasets (> 50,000 items)
  • Performance is critical
  • Building or accumulating data
  • Bulk operations (imports, migrations)

Converting Between Modes

Start with immutable, convert if needed

$array = JsArray::from([1, 2, 3]);
if ($arraySize > 50000) {
$array->toMutable(); // Switch to mutable mode
}

Create mutable copy without affecting original

$copy = $array->getMutableCopy();
$copy->map(...)->filter(...);
echo$array->toArray(); // Original unchanged

Convert back to immutable

$safeArray = $copy->toImmutable();

Check the mode:

$array->isMutable; // bool$array->isImmutable; // bool

Testing

Run tests:

composer test

Tests include:

  • 190+ test cases
  • All methods covered
  • Edge cases tested
  • Immutable/mutable modes tested

Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure tests pass
  5. Submit a pull request

Documentation Files


License

MIT License - See LICENSE for details.


Support


Changelog

v2.1.0

✨ Enhanced native PHP interoperability:
  • Iteration (Iterator): Seamless foreach loop support
  • ArrayAccess: Access elements using array syntax (e.g., $array[0])
  • Counting (Countable): Native count() function integration
  • JSON Serialization (JsonSerializable): Direct json_encode() support
  • JSON Deserialization: Create JsArray from JSON strings with fromJson()

v2.0.0

  • ✨ Added mutable mode for performance
  • ✨ 5 new methods (shift, unshift, indexOf, lastIndexOf, reverse)
  • ✨ Flexible callback signatures (use only params you need!)
  • ✨ Depth parameter for flat()
  • 🐛 Fixed filter re-indexing for numeric arrays
  • 📚 Comprehensive documentation files

v1.0.0

  • Initial release

JsArray - JavaScript Arrays in PHP

About

A PHP implementation of JavaScript Array methods with immutable operations and identical API behavior.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JsArray - JavaScript Arrays in PHP

Packagist VersionPHP VersionLicenseTests

Write JavaScript Array code in PHP. Familiar, powerful, and intuitive API for working with arrays.

If you know JavaScript arrays, you already know JsArray.


What is JsArray?

JsArray brings the beloved JavaScript Array methods to PHP with:

  • Familiar API - Same methods, same behavior as JavaScript
  • Full Type Safety - PHP 8+ with complete type hints
  • Flexible - Choose immutable (safe) or mutable (fast) mode
  • Pure PHP - Zero dependencies, lightweight
  • Native PHP Interoperability - Behaves like a first-class PHP collection

Installation

composer require jsarray/jsarray

Requirements: PHP 8.0+


Quick Start

The Basics

useJsArray\JsArray;
$numbers = JsArray::from([1, 2, 3, 4, 5]);
// Transform data$doubled = $numbers->map(fn($number) => $number * 2);
// Keep only matching items$evenNumbers = $numbers->filter(fn($number) => $number % 2 === 0);
// Combine operations (method chaining)$result = $numbers
->filter(fn($number) => $number > 2)
->map(fn($number) => $number * 10)
->toArray();
// Result: [30, 40, 50]

Working with Objects

$users = JsArray::from([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 17],
['name' => 'Charlie', 'age' => 30],
]);
// Get names of adults$adultNames = $users
->filter(fn($user) => $user['age'] >= 18)
->map(fn($user) => $user['name'])
->toArray();
// Result: ['Alice', 'Charlie']

Flexible Callback Signatures

Use only the parameters you need:

// Just the item value$numbers->map(fn($number) => $number * 2);
// Item and its index$items->filter(fn($item, $index) => $index > 0);
$numbers->forEach(fn($number, $index) => echo "$index: $number");
// Full context (item, index, and array reference)$array->map(fn($item, $index, $array) =>
$item > ($array->length / 2) ? 'big' : 'small'
);

JsArray automatically detects which parameters your callback uses. No configuration needed!


Native PHP Interoperability

JsArray behaves like a first‑class PHP collection and integrates naturally with core language features.

Iteration (Iterator)

Use JsArray directly in foreach loops:

$items = JsArray::from([1, 2, 3]);
foreach ($itemsas$value) {
echo$value;
}

No conversion needed.

ArrayAccess

Use JsArray as an array:

$items = JsArray::from([1, 2, 3]);
echo$items[0]; // 1$items[0] = 10;
echo$items[0]; // 10$items->toArray(); // [10, 2, 3]

Counting (Countable)

Use PHP’s native count() function:

$items = JsArray::from([1, 2, 3]);
echocount($items); // 3

Equivalent to:

$items->length;

JSON Serialization (JsonSerializable)

Serialize JsArray cleanly using json_encode():

$items = JsArray::from([1, 2, 3]);
echojson_encode($items);

Output:

[1, 2, 3]

Create a JsArray from a JSON string:

$json = '[1, 2, 3]';
$items = JsArray::fromJson($json);
// Now you can use JsArray methods$doubled = $items->map(fn($n) => $n * 2);

This makes JsArray ideal for APIs, responses, and data transport without extra mapping.


Core Features

Transformation

$array->map(fn($item) => $item * 2); // Transform each item$array->filter(fn($item) => $item > 10); // Keep matching items$array->reduce(fn($total, $item) => $total + $item, 0); // Combine to single value$array->flat(); // Flatten nested arrays$array->flatMap(fn($item) => [$item, $item * 2]); // Map then flatten

Search

$array->find(fn($item) => $item > 100); // Get first match$array->findIndex(fn($item) => $item > 100); // Get index of first match$array->includes(50); // Check if value exists$array->indexOf(50); // Get index of value$array->some(fn($item) => $item > 100); // Check if ANY match$array->every(fn($item) => $item > 0); // Check if ALL match

Access

$array->first(); // Get first item$array->last(); // Get last item$array->at(0); // Get item at index$array->at(-1); // Get last item (negative index)$array->length; // Get array length

Manipulation

$array->push($item1, $item2); // Add items to end$array->pop(); // Remove and return last item$array->unshift($item1, $item2); // Add items to start$array->shift(); // Remove and return first item$array->slice(1, 3); // Extract portion$array->reverse(); // Reverse order$array->sort(); // Sort items$array->concat($otherArray); // Combine arrays$array->join(', '); // Join into string

Other

$array->keys(); // Get all keys$array->values(); // Get all values$array->toArray(); // Convert to native PHP array$array->forEach(fn($item) => echo $item); // Execute for each item$array->toImmutable(); // Convert array to immutable$array->toMutable(); // Convert array to mutable$array->getMutableCopy(); // Create new mutable copy of array$array->getImmutableCopy(); // Create new immutable copy of array

Two Modes: Immutable & Mutable

Immutable Mode (Default)

Creates a new array for each operation. Original is never changed.

$original = JsArray::from([1, 2, 3]);
$doubled = $original->map(fn ($n) => $n * 2);
$original->toArray(); // [1, 2, 3]$doubled->toArray(); // [2, 4, 6]

Use immutable when:

  • Processing user input
  • Data safety matters
  • Building complex logic
  • Working with small to medium arrays (< 10,000 items)

Mutable Mode (Fast)

Modifies the array in-place. Much faster for large datasets.

$array = JsArray::mutable([1, 2, 3, 4, 5]);
$array
->map(fn ($n) => $n * 2)
->filter(fn ($n) => $n > 2);
$array->toArray(); // [4, 6, 8, 10]

Use mutable when:

  • Processing large datasets (> 50,000 items)
  • Performance is critical
  • Building or accumulating data
  • Bulk operations (imports, migrations)

Converting Between Modes

Start with immutable, convert if needed

$array = JsArray::from([1, 2, 3]);
if ($arraySize > 50000) {
$array->toMutable(); // Switch to mutable mode
}

Create mutable copy without affecting original

$copy = $array->getMutableCopy();
$copy->map(...)->filter(...);
echo$array->toArray(); // Original unchanged

Convert back to immutable

$safeArray = $copy->toImmutable();

Check the mode:

$array->isMutable; // bool$array->isImmutable; // bool

Testing

Run tests:

composer test

Tests include:

  • 190+ test cases
  • All methods covered
  • Edge cases tested
  • Immutable/mutable modes tested

Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure tests pass
  5. Submit a pull request

Documentation Files


License

MIT License - See LICENSE for details.


Support


Changelog

v2.1.0

✨ Enhanced native PHP interoperability:
  • Iteration (Iterator): Seamless foreach loop support
  • ArrayAccess: Access elements using array syntax (e.g., $array[0])
  • Counting (Countable): Native count() function integration
  • JSON Serialization (JsonSerializable): Direct json_encode() support
  • JSON Deserialization: Create JsArray from JSON strings with fromJson()

v2.0.0

  • ✨ Added mutable mode for performance
  • ✨ 5 new methods (shift, unshift, indexOf, lastIndexOf, reverse)
  • ✨ Flexible callback signatures (use only params you need!)
  • ✨ Depth parameter for flat()
  • 🐛 Fixed filter re-indexing for numeric arrays
  • 📚 Comprehensive documentation files

v1.0.0

  • Initial release

JsArray - JavaScript Arrays in PHP

About

A PHP implementation of JavaScript Array methods with immutable operations and identical API behavior.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JsArray - JavaScript Arrays in PHP

Packagist VersionPHP VersionLicenseTests

Write JavaScript Array code in PHP. Familiar, powerful, and intuitive API for working with arrays.

If you know JavaScript arrays, you already know JsArray.


What is JsArray?

JsArray brings the beloved JavaScript Array methods to PHP with:

  • Familiar API - Same methods, same behavior as JavaScript
  • Full Type Safety - PHP 8+ with complete type hints
  • Flexible - Choose immutable (safe) or mutable (fast) mode
  • Pure PHP - Zero dependencies, lightweight
  • Native PHP Interoperability - Behaves like a first-class PHP collection

Installation

composer require jsarray/jsarray

Requirements: PHP 8.0+


Quick Start

The Basics

useJsArray\JsArray;
$numbers = JsArray::from([1, 2, 3, 4, 5]);
// Transform data$doubled = $numbers->map(fn($number) => $number * 2);
// Keep only matching items$evenNumbers = $numbers->filter(fn($number) => $number % 2 === 0);
// Combine operations (method chaining)$result = $numbers
->filter(fn($number) => $number > 2)
->map(fn($number) => $number * 10)
->toArray();
// Result: [30, 40, 50]

Working with Objects

$users = JsArray::from([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 17],
['name' => 'Charlie', 'age' => 30],
]);
// Get names of adults$adultNames = $users
->filter(fn($user) => $user['age'] >= 18)
->map(fn($user) => $user['name'])
->toArray();
// Result: ['Alice', 'Charlie']

Flexible Callback Signatures

Use only the parameters you need:

// Just the item value$numbers->map(fn($number) => $number * 2);
// Item and its index$items->filter(fn($item, $index) => $index > 0);
$numbers->forEach(fn($number, $index) => echo "$index: $number");
// Full context (item, index, and array reference)$array->map(fn($item, $index, $array) =>
$item > ($array->length / 2) ? 'big' : 'small'
);

JsArray automatically detects which parameters your callback uses. No configuration needed!


Native PHP Interoperability

JsArray behaves like a first‑class PHP collection and integrates naturally with core language features.

Iteration (Iterator)

Use JsArray directly in foreach loops:

$items = JsArray::from([1, 2, 3]);
foreach ($itemsas$value) {
echo$value;
}

No conversion needed.

ArrayAccess

Use JsArray as an array:

$items = JsArray::from([1, 2, 3]);
echo$items[0]; // 1$items[0] = 10;
echo$items[0]; // 10$items->toArray(); // [10, 2, 3]

Counting (Countable)

Use PHP’s native count() function:

$items = JsArray::from([1, 2, 3]);
echocount($items); // 3

Equivalent to:

$items->length;

JSON Serialization (JsonSerializable)

Serialize JsArray cleanly using json_encode():

$items = JsArray::from([1, 2, 3]);
echojson_encode($items);

Output:

[1, 2, 3]

Create a JsArray from a JSON string:

$json = '[1, 2, 3]';
$items = JsArray::fromJson($json);
// Now you can use JsArray methods$doubled = $items->map(fn($n) => $n * 2);

This makes JsArray ideal for APIs, responses, and data transport without extra mapping.


Core Features

Transformation

$array->map(fn($item) => $item * 2); // Transform each item$array->filter(fn($item) => $item > 10); // Keep matching items$array->reduce(fn($total, $item) => $total + $item, 0); // Combine to single value$array->flat(); // Flatten nested arrays$array->flatMap(fn($item) => [$item, $item * 2]); // Map then flatten

Search

$array->find(fn($item) => $item > 100); // Get first match$array->findIndex(fn($item) => $item > 100); // Get index of first match$array->includes(50); // Check if value exists$array->indexOf(50); // Get index of value$array->some(fn($item) => $item > 100); // Check if ANY match$array->every(fn($item) => $item > 0); // Check if ALL match

Access

$array->first(); // Get first item$array->last(); // Get last item$array->at(0); // Get item at index$array->at(-1); // Get last item (negative index)$array->length; // Get array length

Manipulation

$array->push($item1, $item2); // Add items to end$array->pop(); // Remove and return last item$array->unshift($item1, $item2); // Add items to start$array->shift(); // Remove and return first item$array->slice(1, 3); // Extract portion$array->reverse(); // Reverse order$array->sort(); // Sort items$array->concat($otherArray); // Combine arrays$array->join(', '); // Join into string

Other

$array->keys(); // Get all keys$array->values(); // Get all values$array->toArray(); // Convert to native PHP array$array->forEach(fn($item) => echo $item); // Execute for each item$array->toImmutable(); // Convert array to immutable$array->toMutable(); // Convert array to mutable$array->getMutableCopy(); // Create new mutable copy of array$array->getImmutableCopy(); // Create new immutable copy of array

Two Modes: Immutable & Mutable

Immutable Mode (Default)

Creates a new array for each operation. Original is never changed.

$original = JsArray::from([1, 2, 3]);
$doubled = $original->map(fn ($n) => $n * 2);
$original->toArray(); // [1, 2, 3]$doubled->toArray(); // [2, 4, 6]

Use immutable when:

  • Processing user input
  • Data safety matters
  • Building complex logic
  • Working with small to medium arrays (< 10,000 items)

Mutable Mode (Fast)

Modifies the array in-place. Much faster for large datasets.

$array = JsArray::mutable([1, 2, 3, 4, 5]);
$array
->map(fn ($n) => $n * 2)
->filter(fn ($n) => $n > 2);
$array->toArray(); // [4, 6, 8, 10]

Use mutable when:

  • Processing large datasets (> 50,000 items)
  • Performance is critical
  • Building or accumulating data
  • Bulk operations (imports, migrations)

Converting Between Modes

Start with immutable, convert if needed

$array = JsArray::from([1, 2, 3]);
if ($arraySize > 50000) {
$array->toMutable(); // Switch to mutable mode
}

Create mutable copy without affecting original

$copy = $array->getMutableCopy();
$copy->map(...)->filter(...);
echo$array->toArray(); // Original unchanged

Convert back to immutable

$safeArray = $copy->toImmutable();

Check the mode:

$array->isMutable; // bool$array->isImmutable; // bool

Testing

Run tests:

composer test

Tests include:

  • 190+ test cases
  • All methods covered
  • Edge cases tested
  • Immutable/mutable modes tested

Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure tests pass
  5. Submit a pull request

Documentation Files


License

MIT License - See LICENSE for details.


Support


Changelog

v2.1.0

✨ Enhanced native PHP interoperability:
  • Iteration (Iterator): Seamless foreach loop support
  • ArrayAccess: Access elements using array syntax (e.g., $array[0])
  • Counting (Countable): Native count() function integration
  • JSON Serialization (JsonSerializable): Direct json_encode() support
  • JSON Deserialization: Create JsArray from JSON strings with fromJson()

v2.0.0

  • ✨ Added mutable mode for performance
  • ✨ 5 new methods (shift, unshift, indexOf, lastIndexOf, reverse)
  • ✨ Flexible callback signatures (use only params you need!)
  • ✨ Depth parameter for flat()
  • 🐛 Fixed filter re-indexing for numeric arrays
  • 📚 Comprehensive documentation files

v1.0.0

  • Initial release

JsArray - JavaScript Arrays in PHP

About

A PHP implementation of JavaScript Array methods with immutable operations and identical API behavior.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JsArray - JavaScript Arrays in PHP

Packagist VersionPHP VersionLicenseTests

Write JavaScript Array code in PHP. Familiar, powerful, and intuitive API for working with arrays.

If you know JavaScript arrays, you already know JsArray.


What is JsArray?

JsArray brings the beloved JavaScript Array methods to PHP with:

  • Familiar API - Same methods, same behavior as JavaScript
  • Full Type Safety - PHP 8+ with complete type hints
  • Flexible - Choose immutable (safe) or mutable (fast) mode
  • Pure PHP - Zero dependencies, lightweight
  • Native PHP Interoperability - Behaves like a first-class PHP collection

Installation

composer require jsarray/jsarray

Requirements: PHP 8.0+


Quick Start

The Basics

useJsArray\JsArray;
$numbers = JsArray::from([1, 2, 3, 4, 5]);
// Transform data$doubled = $numbers->map(fn($number) => $number * 2);
// Keep only matching items$evenNumbers = $numbers->filter(fn($number) => $number % 2 === 0);
// Combine operations (method chaining)$result = $numbers
->filter(fn($number) => $number > 2)
->map(fn($number) => $number * 10)
->toArray();
// Result: [30, 40, 50]

Working with Objects

$users = JsArray::from([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 17],
['name' => 'Charlie', 'age' => 30],
]);
// Get names of adults$adultNames = $users
->filter(fn($user) => $user['age'] >= 18)
->map(fn($user) => $user['name'])
->toArray();
// Result: ['Alice', 'Charlie']

Flexible Callback Signatures

Use only the parameters you need:

// Just the item value$numbers->map(fn($number) => $number * 2);
// Item and its index$items->filter(fn($item, $index) => $index > 0);
$numbers->forEach(fn($number, $index) => echo "$index: $number");
// Full context (item, index, and array reference)$array->map(fn($item, $index, $array) =>
$item > ($array->length / 2) ? 'big' : 'small'
);

JsArray automatically detects which parameters your callback uses. No configuration needed!


Native PHP Interoperability

JsArray behaves like a first‑class PHP collection and integrates naturally with core language features.

Iteration (Iterator)

Use JsArray directly in foreach loops:

$items = JsArray::from([1, 2, 3]);
foreach ($itemsas$value) {
echo$value;
}

No conversion needed.

ArrayAccess

Use JsArray as an array:

$items = JsArray::from([1, 2, 3]);
echo$items[0]; // 1$items[0] = 10;
echo$items[0]; // 10$items->toArray(); // [10, 2, 3]

Counting (Countable)

Use PHP’s native count() function:

$items = JsArray::from([1, 2, 3]);
echocount($items); // 3

Equivalent to:

$items->length;

JSON Serialization (JsonSerializable)

Serialize JsArray cleanly using json_encode():

$items = JsArray::from([1, 2, 3]);
echojson_encode($items);

Output:

[1, 2, 3]

Create a JsArray from a JSON string:

$json = '[1, 2, 3]';
$items = JsArray::fromJson($json);
// Now you can use JsArray methods$doubled = $items->map(fn($n) => $n * 2);

This makes JsArray ideal for APIs, responses, and data transport without extra mapping.


Core Features

Transformation

$array->map(fn($item) => $item * 2); // Transform each item$array->filter(fn($item) => $item > 10); // Keep matching items$array->reduce(fn($total, $item) => $total + $item, 0); // Combine to single value$array->flat(); // Flatten nested arrays$array->flatMap(fn($item) => [$item, $item * 2]); // Map then flatten

Search

$array->find(fn($item) => $item > 100); // Get first match$array->findIndex(fn($item) => $item > 100); // Get index of first match$array->includes(50); // Check if value exists$array->indexOf(50); // Get index of value$array->some(fn($item) => $item > 100); // Check if ANY match$array->every(fn($item) => $item > 0); // Check if ALL match

Access

$array->first(); // Get first item$array->last(); // Get last item$array->at(0); // Get item at index$array->at(-1); // Get last item (negative index)$array->length; // Get array length

Manipulation

$array->push($item1, $item2); // Add items to end$array->pop(); // Remove and return last item$array->unshift($item1, $item2); // Add items to start$array->shift(); // Remove and return first item$array->slice(1, 3); // Extract portion$array->reverse(); // Reverse order$array->sort(); // Sort items$array->concat($otherArray); // Combine arrays$array->join(', '); // Join into string

Other

$array->keys(); // Get all keys$array->values(); // Get all values$array->toArray(); // Convert to native PHP array$array->forEach(fn($item) => echo $item); // Execute for each item$array->toImmutable(); // Convert array to immutable$array->toMutable(); // Convert array to mutable$array->getMutableCopy(); // Create new mutable copy of array$array->getImmutableCopy(); // Create new immutable copy of array

Two Modes: Immutable & Mutable

Immutable Mode (Default)

Creates a new array for each operation. Original is never changed.

$original = JsArray::from([1, 2, 3]);
$doubled = $original->map(fn ($n) => $n * 2);
$original->toArray(); // [1, 2, 3]$doubled->toArray(); // [2, 4, 6]

Use immutable when:

  • Processing user input
  • Data safety matters
  • Building complex logic
  • Working with small to medium arrays (< 10,000 items)

Mutable Mode (Fast)

Modifies the array in-place. Much faster for large datasets.

$array = JsArray::mutable([1, 2, 3, 4, 5]);
$array
->map(fn ($n) => $n * 2)
->filter(fn ($n) => $n > 2);
$array->toArray(); // [4, 6, 8, 10]

Use mutable when:

  • Processing large datasets (> 50,000 items)
  • Performance is critical
  • Building or accumulating data
  • Bulk operations (imports, migrations)

Converting Between Modes

Start with immutable, convert if needed

$array = JsArray::from([1, 2, 3]);
if ($arraySize > 50000) {
$array->toMutable(); // Switch to mutable mode
}

Create mutable copy without affecting original

$copy = $array->getMutableCopy();
$copy->map(...)->filter(...);
echo$array->toArray(); // Original unchanged

Convert back to immutable

$safeArray = $copy->toImmutable();

Check the mode:

$array->isMutable; // bool$array->isImmutable; // bool

Testing

Run tests:

composer test

Tests include:

  • 190+ test cases
  • All methods covered
  • Edge cases tested
  • Immutable/mutable modes tested

Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure tests pass
  5. Submit a pull request

Documentation Files


License

MIT License - See LICENSE for details.


Support


Changelog

v2.1.0

✨ Enhanced native PHP interoperability:
  • Iteration (Iterator): Seamless foreach loop support
  • ArrayAccess: Access elements using array syntax (e.g., $array[0])
  • Counting (Countable): Native count() function integration
  • JSON Serialization (JsonSerializable): Direct json_encode() support
  • JSON Deserialization: Create JsArray from JSON strings with fromJson()

v2.0.0

  • ✨ Added mutable mode for performance
  • ✨ 5 new methods (shift, unshift, indexOf, lastIndexOf, reverse)
  • ✨ Flexible callback signatures (use only params you need!)
  • ✨ Depth parameter for flat()
  • 🐛 Fixed filter re-indexing for numeric arrays
  • 📚 Comprehensive documentation files

v1.0.0

  • Initial release

JsArray - JavaScript Arrays in PHP

About

A PHP implementation of JavaScript Array methods with immutable operations and identical API behavior.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JsArray - JavaScript Arrays in PHP

Packagist VersionPHP VersionLicenseTests

Write JavaScript Array code in PHP. Familiar, powerful, and intuitive API for working with arrays.

If you know JavaScript arrays, you already know JsArray.


What is JsArray?

JsArray brings the beloved JavaScript Array methods to PHP with:

  • Familiar API - Same methods, same behavior as JavaScript
  • Full Type Safety - PHP 8+ with complete type hints
  • Flexible - Choose immutable (safe) or mutable (fast) mode
  • Pure PHP - Zero dependencies, lightweight
  • Native PHP Interoperability - Behaves like a first-class PHP collection

Installation

composer require jsarray/jsarray

Requirements: PHP 8.0+


Quick Start

The Basics

useJsArray\JsArray;
$numbers = JsArray::from([1, 2, 3, 4, 5]);
// Transform data$doubled = $numbers->map(fn($number) => $number * 2);
// Keep only matching items$evenNumbers = $numbers->filter(fn($number) => $number % 2 === 0);
// Combine operations (method chaining)$result = $numbers
->filter(fn($number) => $number > 2)
->map(fn($number) => $number * 10)
->toArray();
// Result: [30, 40, 50]

Working with Objects

$users = JsArray::from([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 17],
['name' => 'Charlie', 'age' => 30],
]);
// Get names of adults$adultNames = $users
->filter(fn($user) => $user['age'] >= 18)
->map(fn($user) => $user['name'])
->toArray();
// Result: ['Alice', 'Charlie']

Flexible Callback Signatures

Use only the parameters you need:

// Just the item value$numbers->map(fn($number) => $number * 2);
// Item and its index$items->filter(fn($item, $index) => $index > 0);
$numbers->forEach(fn($number, $index) => echo "$index: $number");
// Full context (item, index, and array reference)$array->map(fn($item, $index, $array) =>
$item > ($array->length / 2) ? 'big' : 'small'
);

JsArray automatically detects which parameters your callback uses. No configuration needed!


Native PHP Interoperability

JsArray behaves like a first‑class PHP collection and integrates naturally with core language features.

Iteration (Iterator)

Use JsArray directly in foreach loops:

$items = JsArray::from([1, 2, 3]);
foreach ($itemsas$value) {
echo$value;
}

No conversion needed.

ArrayAccess

Use JsArray as an array:

$items = JsArray::from([1, 2, 3]);
echo$items[0]; // 1$items[0] = 10;
echo$items[0]; // 10$items->toArray(); // [10, 2, 3]

Counting (Countable)

Use PHP’s native count() function:

$items = JsArray::from([1, 2, 3]);
echocount($items); // 3

Equivalent to:

$items->length;

JSON Serialization (JsonSerializable)

Serialize JsArray cleanly using json_encode():

$items = JsArray::from([1, 2, 3]);
echojson_encode($items);

Output:

[1, 2, 3]

Create a JsArray from a JSON string:

$json = '[1, 2, 3]';
$items = JsArray::fromJson($json);
// Now you can use JsArray methods$doubled = $items->map(fn($n) => $n * 2);

This makes JsArray ideal for APIs, responses, and data transport without extra mapping.


Core Features

Transformation

$array->map(fn($item) => $item * 2); // Transform each item$array->filter(fn($item) => $item > 10); // Keep matching items$array->reduce(fn($total, $item) => $total + $item, 0); // Combine to single value$array->flat(); // Flatten nested arrays$array->flatMap(fn($item) => [$item, $item * 2]); // Map then flatten

Search

$array->find(fn($item) => $item > 100); // Get first match$array->findIndex(fn($item) => $item > 100); // Get index of first match$array->includes(50); // Check if value exists$array->indexOf(50); // Get index of value$array->some(fn($item) => $item > 100); // Check if ANY match$array->every(fn($item) => $item > 0); // Check if ALL match

Access

$array->first(); // Get first item$array->last(); // Get last item$array->at(0); // Get item at index$array->at(-1); // Get last item (negative index)$array->length; // Get array length

Manipulation

$array->push($item1, $item2); // Add items to end$array->pop(); // Remove and return last item$array->unshift($item1, $item2); // Add items to start$array->shift(); // Remove and return first item$array->slice(1, 3); // Extract portion$array->reverse(); // Reverse order$array->sort(); // Sort items$array->concat($otherArray); // Combine arrays$array->join(', '); // Join into string

Other

$array->keys(); // Get all keys$array->values(); // Get all values$array->toArray(); // Convert to native PHP array$array->forEach(fn($item) => echo $item); // Execute for each item$array->toImmutable(); // Convert array to immutable$array->toMutable(); // Convert array to mutable$array->getMutableCopy(); // Create new mutable copy of array$array->getImmutableCopy(); // Create new immutable copy of array

Two Modes: Immutable & Mutable

Immutable Mode (Default)

Creates a new array for each operation. Original is never changed.

$original = JsArray::from([1, 2, 3]);
$doubled = $original->map(fn ($n) => $n * 2);
$original->toArray(); // [1, 2, 3]$doubled->toArray(); // [2, 4, 6]

Use immutable when:

  • Processing user input
  • Data safety matters
  • Building complex logic
  • Working with small to medium arrays (< 10,000 items)

Mutable Mode (Fast)

Modifies the array in-place. Much faster for large datasets.

$array = JsArray::mutable([1, 2, 3, 4, 5]);
$array
->map(fn ($n) => $n * 2)
->filter(fn ($n) => $n > 2);
$array->toArray(); // [4, 6, 8, 10]

Use mutable when:

  • Processing large datasets (> 50,000 items)
  • Performance is critical
  • Building or accumulating data
  • Bulk operations (imports, migrations)

Converting Between Modes

Start with immutable, convert if needed

$array = JsArray::from([1, 2, 3]);
if ($arraySize > 50000) {
$array->toMutable(); // Switch to mutable mode
}

Create mutable copy without affecting original

$copy = $array->getMutableCopy();
$copy->map(...)->filter(...);
echo$array->toArray(); // Original unchanged

Convert back to immutable

$safeArray = $copy->toImmutable();

Check the mode:

$array->isMutable; // bool$array->isImmutable; // bool

Testing

Run tests:

composer test

Tests include:

  • 190+ test cases
  • All methods covered
  • Edge cases tested
  • Immutable/mutable modes tested

Contributing

We welcome contributions!

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure tests pass
  5. Submit a pull request

Documentation Files


License

MIT License - See LICENSE for details.


Support


Changelog

v2.1.0

✨ Enhanced native PHP interoperability:
  • Iteration (Iterator): Seamless foreach loop support
  • ArrayAccess: Access elements using array syntax (e.g., $array[0])
  • Counting (Countable): Native count() function integration
  • JSON Serialization (JsonSerializable): Direct json_encode() support
  • JSON Deserialization: Create JsArray from JSON strings with fromJson()

v2.0.0

  • ✨ Added mutable mode for performance
  • ✨ 5 new methods (shift, unshift, indexOf, lastIndexOf, reverse)
  • ✨ Flexible callback signatures (use only params you need!)
  • ✨ Depth parameter for flat()
  • 🐛 Fixed filter re-indexing for numeric arrays
  • 📚 Comprehensive documentation files

v1.0.0

  • Initial release

JsArray - JavaScript Arrays in PHP

About

A PHP implementation of JavaScript Array methods with immutable operations and identical API behavior.

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages