Learn php as a C++ Developer

Written by Arne in Let's make software , tagged with C++ development php programming

It’s often easier to learn a new programming language if you see examples side by side by a programming language you already know. This helped me a lot when I started learning Swift. As I already knew php and C++, it helped me to see how it’s done in Swift.

When you already know C++, then this article will help you to get started in php. This article could also help you if you want to learn C++ and have knowledge of php. The examples are in php version 8.

Table of Contents

Basics

You can test and run php code in the browser at https://onlinephp.io.

File Endings

In php all files are ending with .php. Wether it’s an implementation or header file like includes.

// php
file_include.php
file_impl.php

// C++
file_include.h
file_impl.cpp

Entry points

As php is an interpreter language you can run each file through the interpreter and all direct calls in that file will be executed. An entry point such as int main() doesn’t exist. All files that are starting with <?php are interpreted by the php runtime.

// php
<?php
echo "hello world";

// C++
int main() {
    // ...
}

Print to console

When you use echo or print the line does not terminate with a \n newline character. You have to add that explicitly.

// php
echo "output string\n"; # no return
# or 
print "output\n"; # returns int

// C++
std::cout << "Hello World" << std::endl;

Fundamental Types

php fundamental types are similar to C++ and other languages.

String

// php
"this is a string"

// C++
"this is also a string"

Int

// php
42

// C++
42

Boolean

// php
true
false

// C++
true
false

Double/Float

// php
1.0

// C++
1.0

Tuple

There is no tuple in php, but you can return an array with different types of value.

// php array with int and boolean values
[1, true]

// C++
tuple{1, true}

Operators

All general operators like arithmetic, assignment, bitwise, comparison, error control, execution, incrementing/decrementing, logical, string, array and type operators are available in php. Most operators are shared between php and C++.

Assignment

// variable declaration and assignment
// php
$count = 0;

// C++
int count = 0;
// constant variable declaration and assignment. Mutation causes an error.
// php
define('ANSWER_TO_EVERYTHING', 42);

// C++
const int answer_to_everything = 42;

Arithmetic

In php you can do an exponentiation assignment by operator but not in C++. In C++ you would need to use a math function like pow(y,z).

// php
1 + 2;
1 - 2;
1 * 2.0;
1 / 2.0;

$age = 41;
$age += 1;
$age -= 1;
$age *= 2;
$age /= 2;
$age %= 4;
$age **= 2; // exponentiation

// C++
1 + 2;
1 - 2;
1 * 2.0;
1 / 2.0;

int age = 41;
age += 1;
age -= 1;
age *= 2;
age /= 2;
age %= 4;

Comparison

// php
$answer = 42;
$answer == 2; // false
$answer != 2; // true
$answer > 2; // true
$answer < 2; // false
$answer >= 42; // true
$answer <= 41; // true

// C++
int answer = 42;
answer == 2; // false
answer != 2; // true
answer > 2; // true
answer < 2; // false
answer >= 42; // true
answer <= 41; // true

Boolean logic

// php
$a = false;
$b = true;

!$a;                  // not
$a && $b;             // and
$a || $b;             // or
$a && ($answer == 42) // compound

// C++
bool a = false;
bool b = true;

!a;                 // not
a && b;             // and
a || b;             // or
a && (answer == 42) // compound

Strings

String literals

// php
$php = "php is awesome.";

// C++
std::string cpp = "C++ is nice."; 

Multiline Strings

// php
$intro = "This could be the start,\n of a long story..."; // Variant 1
$intro = "This could be the start," . PHP_EOL . "of a long story..."; // Variant 2
$intro = <<<HDOC
    This could be the start,
    of a long story...
HDOC; // Variant 3

// C++
std::string intro = 
    "This could be the start,\n"
    "of a long story...";

String interpolation

// php
$domain = "arne";
$tld = "sh";
$url = "{$domain}.{$tld}";

// C++
std::string domain = "arne";
std::string tld = "sh";
std::string url = format(
    "{}.{}", domain, tld
)

Substrings

// php
$planets = "EARTHMARSVENUS";
substr($planets, 0, 5); // EARTH
substr($planets, 5, 4); // MARS
substr($planets, 9); // VENUS

// C++
std::string planets = "EARTHMARSVENUS"; 
planets.substr(0, 5); // EARTH
planets.substr(5, 4); // MARS
planets.substr(9); // VENUS

Arrays

// php
//- Declaration and initialization
$planets = ["Earth", "Mars", "Venus"];


//- Access
$planets[1]; // "Mars"

//- Insert
$planets[] = "Pluto";

//- Remove
unset($planets[1]);
array_splice($planets, 1, 1);

//- Contains 
in_array( "Mars", $planets ) === true;

// C++
//- Declaration and initialization
std::vector<std::string> planets = {
    std::string("Earth"), "Mars", "Venus"
};

//- Access
planets[1]; // "Mars"

//- Insert
planets.push_back("Pluto");
planets.insert(planets.begin(), "Saturn");

//- Remove
planets.erase(planets.begin(), planets.begin() + 1);
planets.pop_back();

//- Contains
std::find(planets.begin(), planets.end(), "Pluto") != planets.end();

Set

There is no equivalent to sets in php. You can use a data structure extension to get a set, collection, hashable etc. but on most web servers this is not available.


Dictionary

// php
$ships = [
    "enterprise" => 1,
    "birds of prey" => 5
];

//- Access
$ships["enterprise"]; // 1
$ships["shuttle"]; // Raises: Warning: Undefined array key "shuttle" in /home/user/scripts/code.php on line 10
$ships["birds of prey"] = 2;

//- Remove
unset($ships["birds of prey"]);

// C++
std::map<std::string, int> ships = {
    {"enterprise", 1},
    {"birds of prey", 5}
};

//- Access
ships["enterprise"]; // 1
ships["shuttle"]; // NULL

ships["birds of prey"] = 2;

//- Remove
ships.erase("birds of prey");

Control Flow

If/Else condition

// php
$cpp = false;
$php = true;

if ($php) { /* ... */ }

if ($php) {
    /* ... */
} else if ($cpp) {
    /* ... */
} else {
    /* ... */
}

// C++
bool cpp = false;
bool php = true;

if (php) { /* ... */ }

if (php) {
    /* ... */
} else if (cpp) {
    /* ... */
} else {
    /* ... */
}

For/Foreach Loop

// php
$ages = [39, 40, 41, 42];
foreach( $ages as $index => $age ) {
    /* ... */
}

for($i = 0; $i < 4; $i++) {
    /* ... */
}

$reverse_array = array_reverse( $ages );
foreach( $reverse_array as $index => $age ) {
    // 42, 41, 40
}

// C++
std::vector<int> ages = {39, 40, 41, 42};
for (auto& age : ages) {
    /* ... */
}

for(int i = 0; i < 4; i++) {
    /* ... */
}

auto it = ages.begin();
for(it; it != ages.begin()+3; ++it) {
    // 39, 40, 41
}

auto it = ages.end();
for(it; it != ages.end()-3; ++it) {
    // 42, 41, 40
}

While loop

// php
$is_running = true;
while ( $is_running ) {
    /* ... */
    $is_running = false;
}

// C++
bool is_running = true;
while ( is_running ) {
    /* ... */
    is_running = false;
}

Switch

// php
$day = 1;
switch($day) {
    case 0:
        echo "Monday";
        break;
    case 1:
        echo "Tuesday";
        break;
    default:
        echo "Weekend :)";
        break;
}

// C++
int day = 1;
switch(day) {
    case 0:
        std::cout << "Monday";
        break;
    case 1:
        std::cout << "Tuesday";
        break;
    default:
        std::cout << "Weekend :)";
}

Functions

In php the function keyword is used to specify a function definition, arguments are specified inside () with the type as a variable name prefix, and : and the type as the return type after the brackets.

// php
function say_hello(): void {
    echo "Hello World\n";
}

function is_version(string $version, string $last_version = "0.0.1"): bool {
    return $version === $last_version;
}

is_version("0.0.1"); // true
is_version("0.0.1", "1.2.3"); // false

// C++
void say_hello() {
    std::cout << "Hello World" << std::endl;
}

bool is_version(std::string version, std::string last_version = "0.0.1") {
    return version == last_version; 
}

Closures

// php
$tiers = ["primary", "secondary", "tertiary"];
$filtered = array_filter($tiers, function(string $value) {
    return substr($value, 0, 1) === "s";
});

// C++
std::vector<std::string> tiers = {"primary", "secondary", "tertiary"};
std::vector<std::string> filtered;
std::copy_if(tiers.begin(), tiers.end(), std::back_inserter(filtered), [](std::string tier) {
    return tier.substr(0, 1) == "s";
});

Structs

In php there are no structs available. The closest you can get is a class with all public methods and members.

// php
class DataContext {
    public int $id;
    public string $name;
    
    public function getName(): string {
        return $this->name;
    }
}

$ctx = new DataContext;
$ctx->name = "Arne";
echo $ctx->getName();

// C++
struct DataContext {
    int id;
    std::string name;
    
    std::string getName() {
        return name;
    }
}

DataContext ctx = {
    .id = 0,
    .name = "Arne"
};
std::cout << ctx.getName();

Classes

// php
class Context {
    private int $ctx_id_;
    private string $data_;
    
    function __construct(string $data) {
        $this->ctx_id_ = 0;
        $this->data_ = $data;
    }
    
    public function getData(): string {
        return $this->data_ . $this->ctx_id_;
    }
    
    public function setCtxId(int $id): void {
        $this->ctx_id_ = $id;
    }
}

$ctx = new Context("This is a strange world.");
$ctx->setCtxId( 42 );
echo $ctx->getData();

// C++
class Context {
public:
    Context(std::string data) {
        this->data_ = data;
        this->ctx_id_ = 0;
    }
    
    std::string getData() const {
        return data_ + " " + std::to_string( ctx_id_ );
    }
    
    void setCtxId(int id) {
        ctx_id_ = id;
    }
        
private:
    std::string data_;
    int ctx_id_;
}

Context ctx = Context("This is a strange world.");
ctx->setCtxId( 42 );
std::cout << ctx->getData() << std::endl;

Error Handling/Exception Handling

php uses the throw keyword inside a try/catch block. There are a lot of ready-made exceptions, but you can roll your own. Exceptions need to be derived from the base class Exception. To make things short: it’s the same in C++.

// php
class PasswordWrongException extends Exception {
    public function __construct($code = 0, Throwable $previous = null) {
        parent::__construct("You shall not pass!", $code, $previous);
    }
}

try {
    // login...
    throw new PasswordWrongException;
} catch(PasswordWrongException $e) {
    echo $e->getMessage();
} catch(Exception $e) {
    // other exception found
}

// C++
class PasswordWrongException: public std::exception {
  virtual const char* what() const throw() {
    return "You shall not pass!";
  }
};

try {
    // login...
    throw PasswordWrongException();
} catch(exception &e) {
    std::cout << e.what() << std::endl;
}

Enums

Since php8 Enumerations are available tool.

// php
enum Rank {
    case ChiefPettyOfficer;
    case Cadet;
    case Ensign;
    case LieutenantJuniorGrade;
    // ...
    case Captain;
}

function greetings(Rank $rank) {
    // ...
}

// C++
enum Rank {
    ChiefPettyOfficer, Cadet, Ensign, LieutenantJuniorGrade, Captain
};
void greetings(Rank rank) {
    // ...
}

That’s it for now. php has a very good documentation site which you can find here. There are plenty of examples on each page.