Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

A - Coming from Python, JavaScript, or Java

One row per construct, the spelling you know on the left, the modern PHP spelling on the right. Where PHP offers an old form and a new one, only the new one is listed.

ConceptPythonJavaScriptJavaPHP
Variablex = 1let x = 1int x = 1;$x = 1;
ConstantX = 1 (convention)const X = 1static final int X = 1;const X = 1;
String interpolationf"hi {name}"`hi ${name}`"hi " + name"hi {$name}"
String concata + ba + ba + b$a . $b
Multi-line string"""..."""`...`"""..."""<<<TXT ... TXT;
Integer divisiona // bMath.trunc(a / b)a / bintdiv($a, $b)
Exponenta ** ba ** bMath.pow(a, b)$a ** $b
Strict equalitya == ba === ba.equals(b)$a === $b
Null coalescinga if a is not None else ba ?? bOptional.ofNullable(a).orElse(b)$a ?? $b
Ternarya if c else bc ? a : bc ? a : b$c ? $a : $b
List literal[1, 2][1, 2]List.of(1, 2)[1, 2]
Dict literal{"k": 1}{k: 1}Map.of("k", 1)['k' => 1]
List appendxs.append(v)xs.push(v)xs.add(v)$xs[] = $v;
Dict lookup with defaultd.get("k", 0)d.k ?? 0d.getOrDefault("k", 0)$d['k'] ?? 0
Lengthlen(xs)xs.lengthxs.size()count($xs)
String lengthlen(s)s.lengths.length()mb_strlen($s)
Slicexs[1:3]xs.slice(1, 3)xs.subList(1, 3)array_slice($xs, 1, 2)
Iterate listfor v in xs:for (const v of xs)for (var v : xs)foreach ($xs as $v)
Iterate dictfor k, v in d.items():for (const [k, v] of Object.entries(d))for (var e : d.entrySet())foreach ($d as $k => $v)
Map[f(v) for v in xs]xs.map(f)xs.stream().map(f)array_map($f, $xs)
Filter[v for v in xs if p(v)]xs.filter(p)xs.stream().filter(p)array_filter($xs, $p)
Lambdalambda x: x * 2x => x * 2x -> x * 2fn($x) => $x * 2
Closure captureby referenceby referenceeffectively finalby value (use ($x) or fn)
Default argumentdef f(x=1):function f(x = 1)overloadfunction f(int $x = 1)
Named argumentf(x=1)f({x: 1})nonef(x: 1)
Variadicdef f(*xs):function f(...xs)void f(int... xs)function f(int ...$xs)
Classclass A:class A {}class A {}class A {}
Constructordef __init__(self, x):constructor(x) {}A(int x) {}public function __construct(public int $x) {}
Instance memberself.xthis.xthis.x$this->x
Static memberA.xA.xA.xA::$x
InterfaceProtocolnone (TS: interface)interface A {}interface A {}
Enumclass C(Enum):none (TS: enum)enum C { A, B }enum C { case A; case B; }
Catch exceptionexcept E as e:catch (e)catch (E e)catch (E $e)
Safe navigationnonea?.bOptional.map$a?->b
String to intint(s)parseInt(s)Integer.parseInt(s)(int) $s
Type checkisinstance(x, A)x instanceof Ax instanceof A$x instanceof A
Printprint(x)console.log(x)System.out.println(x)echo $x;
Importfrom a import Bimport { B } from 'a'import a.B;use A\B;
Package managerpip, pyproject.tomlnpm, package.jsonMaven, pom.xmlComposer, composer.json
Test runnerpytestJest, VitestJUnitPHPUnit, Pest
Formatterblack, ruffPrettiergoogle-java-formatPHP-CS-Fixer, PHP_CodeSniffer
Static analysismypy, pyrighttscthe compilerPHPStan, Psalm
Run a scriptpython a.pynode a.jsjava A.javaphp a.php
REPLpythonnodejshellphp -a

Four things that are different, not just spelled differently

  • A request starts from nothing and ends with nothing. No process stays alive between two requests. How PHP Runs.
  • Arrays are values. Assign or pass one and you get a copy. Objects are handles. Arrays.
  • Closures capture by value, at creation time. A later change to the outer variable is not seen. Functions and Closures.
  • Strict typing is a per-file switch. declare(strict_types=1) governs the calls made from that file, and only that file. Types.