Rosetta Stone: PHP → Phel

See how common PHP patterns translate to Phel. Click a category to filter, or browse them all.

Variable assignment#

PHP

$name = "world";
echo "Hello $name";

Phel

(def name "world")
(println (str "Hello " name))

Constants#

PHP

const TAX_RATE = 0.21;
define('APP_NAME', 'MyApp');

Phel

(def tax-rate 0.21)
(def app-name "MyApp")

Local bindings (let)#

PHP

function area(float $r): float {
    $pi = 3.14159;
    $squared = $r * $r;
    return $pi * $squared;
}

Phel

(defn area [r]
  (let [pi 3.14159
        squared (* r r)]
    (* pi squared)))

Type checking#

PHP

is_string($x);    // true/false
is_int($x);       // true/false
is_null($x);      // true/false
is_array($x);     // true/false

Phel

(string? x)       # true/false
(int? x)          # true/false
(nil? x)          # true/false
(vector? x)       # true/false

Basic function#

PHP

function add(int $a, int $b): int {
    return $a + $b;
}

echo add(2, 3); // 5

Phel

(defn add [a b]
  (+ a b))

(println (add 2 3)) # 5

Default params / multi-arity#

PHP

function greet(string $name = "World"): string {
    return "Hello, $name!";
}

greet();       // "Hello, World!"
greet("Phel"); // "Hello, Phel!"

Phel

(defn greet
  ([] (greet "World"))
  ([name] (str "Hello, " name "!")))

(greet)       # "Hello, World!"
(greet "Phel") # "Hello, Phel!"

Anonymous function#

PHP

$double = fn($x) => $x * 2;

$add = function($a, $b) {
    return $a + $b;
};

echo $double(5); // 10

Phel

(def double |(* $ 2))

(def add (fn [a b] (+ a b)))

(println (double 5)) # 10

Variadic arguments#

PHP

function sum(int ...$numbers): int {
    return array_sum($numbers);
}

echo sum(1, 2, 3, 4); // 10

Phel

(defn sum [& numbers]
  (reduce + 0 numbers))

(println (sum 1 2 3 4)) # 10

Create array / vector#

PHP

$numbers = [1, 2, 3, 4, 5];
$first = $numbers[0];       // 1
$count = count($numbers);   // 5

Phel

(def numbers [1 2 3 4 5])
(def first-num (first numbers))  # 1
(def cnt (count numbers))        # 5

Associative array / map#

PHP

$user = [
    'name' => 'Alice',
    'age' => 30,
    'role' => 'admin',
];
$name = $user['name']; // "Alice"

Phel

(def user {:name "Alice"
           :age 30
           :role "admin"})
(def name (:name user)) # "Alice"

Add element#

PHP

$items = [1, 2, 3];
$items[] = 4;          // [1, 2, 3, 4]

$map = ['a' => 1];
$map['b'] = 2;         // ['a' => 1, 'b' => 2]

Phel

(def items [1 2 3])
(def updated (conj items 4))     # [1 2 3 4]

(def m {:a 1})
(def with-b (assoc m :b 2))     # {:a 1 :b 2}

Remove element#

PHP

$user = ['name' => 'Alice', 'age' => 30];
unset($user['age']);
// ['name' => 'Alice']

$items = [1, 2, 3];
$filtered = array_filter($items, fn($x) => $x !== 2);
// [1, 3]

Phel

(def user {:name "Alice" :age 30})
(dissoc user :age)
# {:name "Alice"}

(def items [1 2 3])
(filter |(not= $ 2) items)
# [1 3]

Nested access#

PHP

$data = [
    'user' => [
        'address' => [
            'city' => 'Berlin',
        ],
    ],
];
$city = $data['user']['address']['city'];

Phel

(def data {:user {:address {:city "Berlin"}}})
(def city (get-in data [:user :address :city]))
# "Berlin"

Concatenation#

PHP

$full = $first . " " . $last;
$greeting = "Hello, " . $name . "!";

Phel

(def full (str first " " last))
(def greeting (str "Hello, " name "!"))

Formatting / interpolation#

PHP

$msg = sprintf("Hello, %s! You are %d.", $name, $age);
$price = sprintf("$%.2f", $amount);

Phel

(def msg (format "Hello, %s! You are %d." name age))
(def price (format "$%.2f" amount))

Split / join#

PHP

$parts = explode(",", "a,b,c");     // ["a", "b", "c"]
$joined = implode("-", $parts);      // "a-b-c"

Phel

(def parts (php/explode "," "a,b,c"))  # PHP array
(def joined (php/implode "-" parts))   # "a-b-c"

PHP

$sub = substr("Hello World", 0, 5);     // "Hello"
$pos = strpos("Hello World", "World");   // 6
$has = str_contains("Hello", "ell");     // true

Phel

(def sub (php/substr "Hello World" 0 5))     # "Hello"
(def pos (php/strpos "Hello World" "World")) # 6
(def has (php/str_contains "Hello" "ell"))   # true

If / else#

PHP

if ($age >= 18) {
    $status = "adult";
} else {
    $status = "minor";
}

Phel

(def status
  (if (>= age 18) "adult" "minor"))

Switch / case#

PHP

switch ($code) {
    case 200: $msg = "OK"; break;
    case 404: $msg = "Not Found"; break;
    case 500: $msg = "Server Error"; break;
    default:  $msg = "Unknown";
}

Phel

(def msg
  (case code
    200 "OK"
    404 "Not Found"
    500 "Server Error"))

Ternary / inline if#

PHP

$label = $count > 0 ? "has items" : "empty";
$display = $user['name'] ?: "Anonymous";

Phel

(def label (if (> count 0) "has items" "empty"))
(def display (or (:name user) "Anonymous"))

Null coalescing / or#

PHP

$name = $input ?? "default";
$host = $config['db']['host'] ?? "localhost";

Phel

(def name (or input "default"))
(def host
  (or (get-in config [:db :host]) "localhost"))

Foreach#

PHP

foreach ($items as $item) {
    echo $item . "\n";
}

foreach ($map as $key => $value) {
    echo "$key: $value\n";
}

Phel

(foreach [item items]
  (println item))

(foreach [k v my-map]
  (println (str k ": " v)))

For with accumulator / reduce#

PHP

$sum = 0;
for ($i = 1; $i <= 10; $i++) {
    $sum += $i;
}
// $sum = 55

Phel

(def sum
  (reduce + 0 (range 1 11)))
# 55

While / loop-recur#

PHP

$n = 10;
$acc = 0;
while ($n > 0) {
    $acc += $n;
    $n--;
}
// $acc = 55

Phel

(loop [n 10
       acc 0]
  (if (> n 0)
    (recur (dec n) (+ acc n))
    acc))
# 55

List comprehension / for#

PHP

$evens = [];
foreach (range(0, 9) as $x) {
    if ($x % 2 === 0) {
        $evens[] = $x * $x;
    }
}
// [0, 4, 16, 36, 64]

Phel

(for [x :range [0 10]
      :when (even? x)]
  (* x x))
# [0 4 16 36 64]

Create object#

PHP

$now = new DateTime();
$date = new DateTimeImmutable("2024-01-15");

Phel

(ns my\module
  (:use \DateTime)
  (:use \DateTimeImmutable))

(def now (php/new DateTime))
(def date (php/new DateTimeImmutable "2024-01-15"))

Method call#

PHP

$formatted = $date->format("Y-m-d");
$result = $date->modify("+1 month")->format("Y-m-d");

Phel

(def formatted (php/-> date (format "Y-m-d")))
(def result
  (php/-> date
    (modify "+1 month")
    (format "Y-m-d")))

Static method#

PHP

$atom = DateTimeImmutable::ATOM;
$parsed = DateTimeImmutable::createFromFormat(
    "Y-m-d",
    "2024-03-22"
);

Phel

(def atom (php/:: DateTimeImmutable ATOM))
(def parsed
  (php/:: DateTimeImmutable
    (createFromFormat "Y-m-d" "2024-03-22")))

Map#

PHP

$doubled = array_map(
    fn($x) => $x * 2,
    [1, 2, 3, 4]
);
// [2, 4, 6, 8]

Phel

(map |(* $ 2) [1 2 3 4])
# [2 4 6 8]

Filter#

PHP

$evens = array_filter(
    [1, 2, 3, 4, 5, 6],
    fn($x) => $x % 2 === 0
);
// [2, 4, 6]

Phel

(filter even? [1 2 3 4 5 6])
# [2 4 6]

Reduce#

PHP

$sum = array_reduce(
    [1, 2, 3, 4],
    fn($carry, $x) => $carry + $x,
    0
);
// 10

Phel

(reduce + 0 [1 2 3 4])
# 10

Pipe / threading#

PHP

// Nested calls (inside-out)
$result = implode(", ",
    array_map(
        fn($x) => strtoupper($x),
        array_filter(
            $names,
            fn($x) => strlen($x) > 3
        )
    )
);

Phel

# Thread-last (top-down, reads naturally)
(def result
  (->> names
       (filter |(> (php/strlen $) 3))
       (map php/strtoupper)
       (php/implode ", ")))