Skip to content

Commit

Permalink
reformatting text
Browse files Browse the repository at this point in the history
  • Loading branch information
niden committed Jan 17, 2024
1 parent 3d37535 commit 6a3dad5
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 187 deletions.
46 changes: 18 additions & 28 deletions docs/language.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
---
layout: default
language: 'en'
version: '0.12'
---

# Basic Syntax
In this chapter, we'll discuss the organization of files and namespaces, variable declarations, miscellaneous syntax conventions, and a few other general concepts.

In this section, we'll delve into the fundamental aspects of Zephir's syntax, covering topics such as file and namespace organization, variable declarations, syntax conventions, and other essential concepts.

## Organizing Code in Files and Namespaces
In PHP, you can place code in any file, without a specific structure. In Zephir, every file must contain a class (and just one class). Every class must have a namespace, and the directory structure must match the names of the classes and namespaces used. (This is similar to PSR-4 autoloading conventions, except it's enforced by the language itself.)

For example, given the following structure, the classes in each file must be:
Zephir introduces a structured approach to code organization. Each file should contain only one class, and every class must be within a namespace. The directory structure aligns with class and namespace names, similar to PSR-4 autoloading conventions.

For example:

```bash
mylibrary/
Expand Down Expand Up @@ -41,17 +37,19 @@ class Exception extends \Exception
}
```

Zephir will raise a compiler exception if a file or class is not located in the expected file, or vice versa.
The file system structure must mirror the namespaces, ensuring consistency.

## Instruction separation
You may have already noticed that there were very few semicolons in the code examples in the previous chapter. You can use semicolons to separate statements and expressions, as in Java, C/C++, PHP, and similar languages:

In Zephir, semicolons can be used to separate statements and expressions, akin to Java, C/C++, and PHP:

```zephir
myObject->myMethod(1, 2, 3); echo "world";
```

## Comments
Zephir supports 'C'/'C++' comments. These are one line comments with `// ...`, and multi line comments with `/* ... */`:

Zephir supports 'C'/'C++' style comments - single-line with `// ...` and multi-line with `/* ... */`:

```zephir
// this is a one line comment
Expand All @@ -61,11 +59,10 @@ Zephir supports 'C'/'C++' comments. These are one line comments with `// ...`, a
*/
```

In most languages, comments are simply text ignored by the compiler/interpreter. In Zephir, multi-line comments are also used as docblocks, and they're exported to the generated code, so they're part of the language!

If a docblock is not located where it is expected, the compiler will throw an exception.
Multi-line comments also serve as docblocks, influencing the generated code and providing documentation.

## Variable Declarations

In Zephir, all variables used in a given scope must be declared. This gives important information to the compiler to perform optimizations and validations. Variables must be unique identifiers, and they cannot be reserved words.

```zephir
Expand All @@ -78,7 +75,7 @@ var b;
var c;
```

Variables can optionally have an initial compatible default value:
Variables can have optional initial default values:

```zephir
// Declaring variables with default values
Expand All @@ -94,7 +91,8 @@ var somevalue, someValue, SomeValue;
```

## Variable Scope
All variables declared are locally scoped to the method where they were declared:

Variables declared are locally scoped to the method where they are defined:

```zephir
namespace Test;
Expand All @@ -116,7 +114,8 @@ class MyClass
```

## Super Globals
Zephir does not support global variables - accessing global variables from the PHP userland is not allowed. However, you can access PHP's super-globals as follows:

Global variables are not supported in Zephir. However, access to PHP's super-globals is possible:

```zephir
// Getting a value from _POST
Expand All @@ -127,17 +126,8 @@ let requestMethod = _SERVER["REQUEST_METHOD"];
```

## Local Symbol Table
Every method or context in PHP has a symbol table that allows you to write variables in a very dynamic way:

```php
<?php

$b = 100;
$a = "b";
echo $$a; // prints 100
```

Zephir does not implement this feature, since all variables are compiled down to low-level variables, and there is no way to know which variables exist in a specific context. If you want to create a variable in the current PHP symbol table, you can use the following syntax:
Zephir does not implement the dynamic variable behavior found in PHP. The language does not have a local symbol table, as all variables are compiled into low-level variables without context awareness. To create a variable in the PHP symbol table, a specific syntax is used:

```zephir
// Set variable $name in PHP
Expand Down
6 changes: 0 additions & 6 deletions docs/license.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
---
layout: default
language: 'en'
version: '0.12'
---

# License

MIT License
Expand Down
13 changes: 7 additions & 6 deletions docs/lifecycle.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Lifecycle hooks
PHP provides several lifecycle events, which extensions can use to perform common initialization or shutdown tasks. Normally, Zephir's own hooks into these events will cover all the setup and tear down your extension will need, but if you find that you need to do something more, there are a few options you can use to pass your own code into these same hooks.

Consider the following diagram:
PHP extensions leverage lifecycle events for common initialization or shutdown tasks. Zephir integrates with these events through hooks, primarily handled in the config.json file. The diagram illustrates the PHP Process/Request Lifecycle, depicting four types of lifecycle hooks: `globals`, `initializers`, `destructors`, and `info`. This chapter focuses on `initializers` and `destructors`.

![The PHP Process/Request Lifecycle](assets/images/content/lifecycle.png)

Expand All @@ -10,7 +9,8 @@ Lifecycle hooks are registered in the `config.json` file. As you can see in the
Each hook in the `config.json` file is an array of objects, which themselves are essentially `include`/`code` pairs. The `include` value will pull in a given C header file, if it hasn't been already, so that the `code` will have access to its contents. The `code` value is the logic run by the hook itself, and while you can technically put any valid C in here, it is **_strongly_** recommended to put logic longer than one or two lines into a separate C source file (such as the one pulled in along with your `include`d header file), and use a single-line function call here.

## initializers
The `initializers` block looks something like this:

The `initializers` block in the `config.json` file includes logic for initialization events. Three key events are targeted: `globals` for global variable space setup, module for extension-specific initialization, and `request` for per-request setup.

```json
{
Expand Down Expand Up @@ -43,10 +43,11 @@ The `initializers` block looks something like this:
}
```

This block is responsible for defining hooks into the Init events shown in the diagram above. There are three of these: `globals` for setting up the global variable space, `module` for setting up anything the extension itself needs to function, and `request` for setting up the extension to handle a single request.
This configuration facilitates the execution of custom C code during the initialization process for various scopes.

## destructors
The `destructors` block looks something like this:

The `destructors` block handles cleanup logic during shutdown events. Four events are addressed: `request` for finalizing data before sending a response, `post-request` for cleanup after sending a response, `module` for extension-specific cleanup, and `globals` for cleaning up the global variable space.

```json
{
Expand Down Expand Up @@ -85,7 +86,7 @@ The `destructors` block looks something like this:
}
```

Much as the `initializers` block is responsible for defining hooks into the Init events shown in the diagram above, _this_ block is responsible for defining hooks into the Shutdown events. There are four of these: `request` for finalizing any data before a response is sent to the client, `post-request` for cleaning up after a response has been sent, `module` for cleaning up after the extension itself before the PHP process shuts down, and `globals` for cleaning up the global variable space.
This configuration enables the execution of custom C code during various shutdown events, ensuring proper cleanup and finalization processes.

[globals]: globals.md
[info]: phpinfo.md
40 changes: 11 additions & 29 deletions docs/motivation.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,22 @@
# Why Zephir?

Today's PHP applications must balance a number of concerns including stability, performance, and functionality. Every PHP application is based on a set of common components, that are also base for many other applications.
In the ever-evolving landscape of PHP applications, developers face challenges in achieving a delicate balance between stability, performance, and functionality. The core components, often in the form of libraries or frameworks, serve as the foundation for many applications. Zephir emerges as a solution to address the need for fast, robust extensions that enhance performance and resource efficiency.

These common components are libraries, frameworks, or a combination of the two. Once installed, frameworks rarely change, and being the foundation of the application, they must be highly functional, and also very fast.
## For PHP Programmers...

Getting fast and robust libraries can be complicated, due to high levels of abstraction that are typically implemented on them. Given the condition that base libraries or frameworks rarely change, there is an opportunity to build extensions that provide this functionality, taking advantage of the compilation improving performance and resource consumption.
PHP, renowned for web application development, provides high productivity through its dynamically typed and interpreted nature. Zephir's integration with PHP running on the Zend Engine empowers developers to create extensions, offering a balance between the flexibility of PHP and the efficiency of a compiled language. While Zephir introduces a compilation step, it adheres to strict standards, providing improved performance.

With Zephir, you can implement object-oriented libraries/frameworks/applications that can be used from PHP, gaining important seconds that can make your application faster while improving the user experience.
## For C Programmers...

## If You Are a PHP Programmer...

PHP is one of the most popular languages in use for the development of web applications. Dynamically typed and interpreted languages like PHP offer very high productivity due to their flexibility.

Since version 4, PHP is based on the Zend Engine implementation. This is a virtual machine that executes the PHP code from its bytecode representation. Zend Engine is present in almost every PHP installation in the world. With Zephir, you can create extensions for PHP running under the Zend Engine.

PHP is hosting Zephir, so they obviously have a lot of similarities; however, they have important differences that give Zephir its own personality. For example, Zephir is more strict, and it could make you less productive compared to PHP due to the compilation step.

## If You Are a C Programmer...

C is one of the most powerful and popular languages ever created. In fact, PHP is written in C, which is one of the reasons why PHP extensions are available for it. C gives you the freedom to manage memory, use low level types and even inline assembly routines.

However, developing big applications in C can take much longer than expected compared to PHP or Zephir, and some errors can be tricky to find if you aren't an experienced developer.

Zephir was designed to be safe, so it does not implement pointers or manual memory management, so if you're a C programmer, you will feel Zephir less powerful, but more friendly, than C.
C, a powerful and widely-used language, serves as the backbone for PHP. Zephir, inheriting some characteristics from C, ensures a safer environment by eliminating pointers and manual memory management. While Zephir may feel less powerful than C to seasoned C programmers, it offers a friendlier experience, emphasizing safety and ease of use.

## Compilation vs Interpretation

Compilation usually slows development down; you will need a bit more patience to compile your code before running it. On the other hand, interpretation tends to reduce code performance in favor of developer productivity. That said, in some cases, there is not any noticeable difference between the speed of interpreted and compiled code.

Zephir requires compilation of your code, but functionality is used from PHP, which is interpreted.

Once the code is compiled, it is not necessary to do so again. Interpreted code is interpreted each time it is run. A developer can decide which parts of their application should be in Zephir and which not.
Zephir's compilation step introduces a slight delay in development, requiring patience for code compilation before execution. However, this approach brings performance benefits without sacrificing the interpretative nature of PHP. Developers have the flexibility to choose which parts of their application to implement in Zephir, achieving a balance between speed and productivity.

## Statically Typed Versus Dynamically Typed Languages

Generally speaking, in a statically typed language, a variable is bound to a particular type for its lifetime. Its type can't be changed and it can only reference type-compatible instances and operations. Languages like C/C++ were implemented with this scheme:
In a statically typed language, a variable is bound to a particular type for its lifetime. Its type can't be changed and it can only reference type-compatible instances and operations. Languages like C/C++ were implemented with this scheme:

```zephir
int a = 0;
Expand All @@ -59,7 +41,8 @@ Another small benefit of static languages is the extra checking the compiler per
Zephir is both statically and dynamically typed, allowing you to take advantage of both approaches where possible.

## Compilation Scheme
Zephir offers native code generation (currently via compilation to C). A compiler like gcc/clang/vc++ optimizes and compiles the code down to machine code. The following graph shows how the process works:

Zephir employs native code generation, compiling to C and utilizing compilers like gcc/clang/vc++ to optimize and produce machine code. This compilation scheme harnesses the capabilities of mature compilers, benefiting from various optimizations provided by these tools.

![compilation scheme](assets/images/content/scheme.png)

Expand All @@ -71,12 +54,11 @@ In addition to the ones provided by Zephir, over time, compilers have implemente

## Code Protection

In some circumstances, the compilation does not significantly improve performance. This may be because the bottleneck is located in the I/O bound portion(s) of the application (quite likely) rather than compute/memory bound. However, compiling code could also bring some level of intellectual protection to your application. With Zephir, producing native binaries, you also get the ability to "hide" the original code to users or customers.
Compilation with Zephir not only enhances performance but also provides a level of intellectual protection. By producing native binaries, Zephir allows developers to "hide" the original code from users or customers, adding an extra layer of security.

## Conclusion

Zephir was not created to replace PHP or C. Instead, we think it is a complement to them, allowing PHP developers to venture into code compilation and static typing. Zephir is an attempt to join good things from the C and PHP worlds, looking for opportunities to make applications faster.

Zephir doesn't aim to replace PHP or C; instead, it complements them. It serves as a bridge, inviting PHP developers to explore code compilation and static typing while preserving the best aspects of both the C and PHP worlds. Zephir is a strategic tool, seeking opportunities to accelerate application development and enhance user experiences.

[gcc_optimizations]: https://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Optimize-Options.html
[llvm_passes]: https://llvm.org/docs/Passes.html
Expand Down
Loading

0 comments on commit 6a3dad5

Please sign in to comment.