PHP For The Impatient
Published: 2020-09-25 04:04:43

We are primarily a PHP shop for about half of the engineering team here at Beanworks. PHP tends to have a bad reputation out there, but with PHP 7 (and potentially PHP 8), it's really becoming a mature and powerful language while keeping its simplicity.

I always tell new engineers with no prior PHP experience that if you're able to write code in any language, you will be able to learn PHP pretty quickly.

In this article we will explore some PHP syntax and compare it to Javascript or Typescript.

I have added 🔁 icon to the ones that have identical syntax.

## Basic Syntax
### Variables

_In PHP land, all variables have to start with a dollar sign `$`_

#### PHP

`$foo = 'bar';`

#### NodeJS
`let foo = 'bar';`

### Template Literals

_You can use variables in strings as long as the string is wrapped with double quote (`"`), strings wrapped with single quotes will not evaluate the variables._

#### PHP
```php
$str = "My name is {$name}"
```

#### NodeJs
```javascript
let str = `My name is ${name}`
```

### Constants 🔁

_PHP has real constants, they must be capitalized, but otherwise the syntax is actually the same_

#### PHP

`const FOO = 'bar';`

#### NodeJS
`const FOO = 'bar';`

### Arrays

#### PHP
```php
$arr = ['a', 'b'];

// you can iterate using foreach
foreach ($arr as $element) {
  ...
}

```

#### NodeJS
```typescript
let arr = ['a', 'b'];

// you can iterate using for ... of
for (let element of arr) {
  ...
}


```

## Objects

_In PHP land, objects are just arrays, associative arrays.  Instead of using `:`, you need to use a [double arrow](https://en.wikipedia.org/wiki/Fat_comma) `=>`_

#### PHP
```php
$myFavouriteVehicles = [
  'Toyota' => ['4Runner','Tacoma'],
  'Ford' => ['Bronco']
];

$fordVehicles = $myFavouriteVehicles['Ford'];

// you can iterate key => value using foreach
foreach ($myFavouriteVehicles as $brand => $vehicles) {
   ...
}
```

#### Javascript
```typescript
let myFavouriteVehicles = {
  'Toyota': ['4Runner','Tacoma'],
  'Ford': ['Bronco']
}

let fordVehicles = myFavouriteVehicles['Bronco'];

// you can iterate key value with Object.entries
for (let [brand, vehicles] of Object.entries(myFavouriteVehicles)) {
  ...
}
```

## Callback functions
_In most of the PHP land, you still have to write call back functions like you had to in ES5 days, arrow function is only recently supported in PHP7.4_

#### PHP 🔁
```php
array_map(function($element) {...}, $arr);

// or in PHP 7.4+ you can use arrow function, no multi line though
array_map(fn($element) => ..., $arr)
```
#### NodeJS
```javascript
arr.map(function (element) {...});

// Arrow function since ES6
arr.map(element => ...);
```
## Classes & Inheritance

_PHP's uses the same syntax extending classes and interfaces_

#### PHP 🔁
` class Foo extends Bar implements FooBarInterface`

#### Typescript
` class Foo extends Bar implements FooBarInterface`

### Type system

_Contrary to popular beliefs, PHP does have a type system that works similar to other OOP languages, and with each new version of PHP, the type system is getting better._


#### PHP

```php
public function writeLine (string content, LineWriter $writer) : string {
    return content;
}
```

#### Typescript
```typescript
public writeLine( content : string, lineWriter lineWriter) : string {
    return content;
}
```

### Invoke Methods
_To invoke a method, you need to use `->` instead of a dot in PHP._

#### PHP
`$logger->log('PHP uses ->');`

#### NodeJs
`logger.log('Node uses .');`


## Generators 🔁

_There is no special syntax in the function signature if you want to use the `yield` keyword_

#### PHP
```php
public function getLaptopBrands() : Iterator {
  yield 'Lenovo';
  yield 'Asus';
  yield 'Dell';
}
```

#### TypeScript
```typescript
public function* getLaptopBrands() : IterableIterator<string> {
  yield 'Lenovo';
  yield 'Asus';
  yield 'Dell';
}
```

### Yield from generator

_In PHP you can use the `yield from` syntax to yield from a generator_

#### PHP
```php
public function getComputerBrands() : Iterator {
  yield from getLaptopBrands();
  yield from getDesktopBrands();
}
```

#### TypeScript
```typescript
public function* getLaptopBrands() : IterableIterator<string> {
  yield* getLaptopBrands();
  yield* getDesktopBrands();
}
```