Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

11 Commits

Folders and files

Repository files navigation

KodiScript PHP SDK

Latest Stable Version License CI

A lightweight, embeddable scripting language for PHP applications.

📖 Documentation complète : docs-kodiscript.dickode.net

Installation

composer require issadicko/kodi-script

Quick Start

use KodiScript\KodiScript;

// Simple evaluation
$result = KodiScript::eval('2 + 3 * 4');
echo $result; // 14

// With variables
$result = KodiScript::run('greeting + ", " + name + "!"', [
    'greeting' => 'Hello',
    'name' => 'World',
]);
echo $result->value; // "Hello, World!"

// Capture output
$result = KodiScript::run('
    let items = ["apple", "banana", "cherry"]
    for (item in items) {
        print(item)
    }
');
print_r($result->output); // ["apple", "banana", "cherry"]

Features

  • Variables: let x = 10
  • Functions: fn(a, b) { return a + b }
  • Control Flow: if, else, for-in, while
  • Data Types: numbers, strings, booleans, arrays, objects
  • Null Safety: ?. (safe access), ?: (elvis operator)
  • 50+ Native Functions: string, math, random, type, array, JSON, encoding, crypto, date/time

🔌 Extensibility

KodiScript is designed to be extensible. You can add your own native functions.

Custom Functions

$result = KodiScript::builder('greet("PHP")')
    ->registerFunction('greet', fn($name) => "Hello, $name!")
    ->execute();

echo $result->value; // "Hello, PHP!"

Laravel Integration Example

class ScriptService
{
    public function __construct(
        private UserRepository $userRepo,
        private NotificationService $notifications
    ) {}

    public function execute(string $script, array $context): ScriptResult
    {
        return KodiScript::builder($script)
            ->withVariables($context)
            ->registerFunction('fetchUser', fn($id) => $this->userRepo->find($id))
            ->registerFunction('sendEmail', fn($to, $subject, $body) => 
                $this->notifications->sendEmail($to, $subject, $body))
            ->registerFunction('calculatePrice', fn($qty, $price, $discount = 0) =>
                $qty * $price * (1 - $discount / 100))
            ->execute();
    }
}

API Reference

KodiScript::eval(source, variables)

Evaluates a script and returns the result value. Throws on error.

KodiScript::run(source, variables)

Runs a script with optional variables and returns ScriptResult.

KodiScript::builder(source)

Creates a builder for advanced configuration.

Native Functions

Category Functions
String toString, toNumber, length, substring, toUpperCase, toLowerCase, trim, split, join, replace, contains, startsWith, endsWith, indexOf
Math abs, floor, ceil, round, min, max, pow, sqrt, sin, cos, tan, log, log10, exp
Random random, randomInt, randomUUID
Type typeOf, isNull, isNumber, isString, isBool
Array size, first, last, reverse, slice, sort, sortBy, unique, flatten, push, concat, range, sum, avg, has
Array (higher-order) map, filter, reduce, find, findIndex, some, every, flatMap
Array (lists) chunk, compact, pluck, zip, fromEntries, difference, intersection, union
Array (by key) groupBy, countBy, indexBy, uniqueBy, sumBy, minBy, maxBy, partition
JSON jsonParse, jsonStringify
Encoding base64Encode, base64Decode, urlEncode, urlDecode
Crypto md5, sha1, sha256
Date/Time now, date, time, datetime, timestamp, formatDate, parseDate, isDate, toISO, year, month, day, hour, minute, second, dayOfWeek, addDays, addHours, addMinutes, addSeconds, addMonths, addYears, diffDays, diffHours, diffMinutes, diffMonths, diffYears, age, startOfDay, endOfDay, startOfMonth, endOfMonth, daysInMonth, isWeekend

All natives also work as methods: items.groupBy("type"), "2026-10-19".addDays(1).

Dates

A date argument is either a number (milliseconds since 1970-01-01T00:00:00Z, fraction truncated toward zero) or ISO text, trimmed:

  • YYYY-MM-DD (midnight UTC);
  • YYYY-MM-DDTHH:mm, YYYY-MM-DDTHH:mm:ss, YYYY-MM-DDTHH:mm:ss.S… (1 to 9 fraction digits, kept to milliseconds by truncation); a space may replace the T;
  • a timed form may end with Z or an offset +HH:mm / -HH:mm / +HHmm. Without a zone the time is UTC.

Fields are validated (2026-02-29 is not a date). Anything else (null, an unreadable string, a boolean, a list, an object) is unreadable, and a date function given an unreadable date returns null instead of raising. A count that is not a number (addDays("2026-10-19", "deux")) still raises.

Every calendar computation (year, month, day, hour, dayOfWeek, startOfDay, addMonths, …) is done in UTC, whatever the server's default time zone. dayOfWeek is 0 for Sunday.

formatDate(date, [format]) (default YYYY-MM-DD) and parseDate(text, format) share these tokens; any other character is copied (formatting) or must match exactly (parsing):

Token Meaning
YYYY 4-digit year
YY last 2 digits of the year (formatting only; read as two literal characters by parseDate)
MM DD month 01-12, day 01-31
HH mm ss hour 00-23, minute, second
SSS millisecond 000-999

parseDate reads exactly the width of each token in digits, requires the whole text to be consumed, and returns null for an out-of-range value (31/02/2026). Missing fields default to January 1st, 00:00:00.000, and to the year 1970 when there is no YYYY.

toISO(date) returns YYYY-MM-DDTHH:mm:ss.SSSZ. addMonths and addYears clamp to the last day of the target month (addMonths("2026-01-31", 1) is 2026-02-28). diffDays, diffHours and diffMinutes are whole units from the first date to the second, truncated toward zero (negative when the second is earlier). diffMonths counts whole calendar months (diffMonths("2026-01-31", "2026-02-28") is 0), diffYears is that count divided by 12, and age(birth, [at]) is diffYears(birth, at) with at defaulting to now.

Numbers are read up to ±8 640 000 000 000 000 ms (year 275760); beyond that a date is unreadable.

Lists

A list argument may be null, which behaves as an empty list; any other non-list value raises. A path is a string of segments separated by .: on an object a segment is a key, on a list a zero-based index written in digits, anything else gives null; "" designates the element itself.

Two values are equal when they have the same type and the same canonical form, so 1 equals 1.0 but not "1", and {a: 1, b: 2} equals {b: 2, a: 1}.

  • chunk(list, size), compact(list), pluck(list, path), zip(list1, list2, …), fromEntries([[key, value], …]).
  • difference(a, b), intersection(a, b), union(list1, list2, …).
  • groupBy, countBy, indexBy, uniqueBy, sumBy, minBy, maxBy, partition, called as groupBy(list, key), where key is a path string or a function fn(item, index). The group key of groupBy, countBy and indexBy is the canonical text of the key value (null gives "null"). sumBy skips null keys and raises on a non-number; minBy and maxBy return the item (the first on ties) and skip null keys. partition puts in the first list the items whose key is not null and not false, as in the other SDKs.

PHP arrays serve both lists and objects: an array is a list when array_is_list() is true, so an object whose keys are 0, 1, 2… in order reads as a list. An empty object produced by groupBy, countBy, indexBy or fromEntries is an empty \stdClass, which prints as {}.

Other Implementations

Language Package
Kotlin Maven Central
Go pkg.go.dev
Dart pub.dev
TypeScript npm

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages