├── .gitignore
├── README.md
├── crowdin.yml
├── el-gr
├── arrays.md
├── builtin-methods.md
├── closures.md
├── command-line.md
├── config.md
├── control-structures.md
├── exceptions.md
├── functions.md
├── globals.md
├── installation.md
├── introduction.md
├── language.md
├── license.md
├── lifecycle.md
├── motivation.md
├── oop.md
├── operator-precedence.md
├── operators.md
├── optimizations.md
├── optimizers.md
├── phpinfo.md
├── right-menu.json
├── sidebar.json
├── static-analysis.md
├── tutorial.md
├── types.md
├── warnings.md
└── welcome.md
├── en
├── arrays.md
├── builtin-methods.md
├── closures.md
├── command-line.md
├── config.md
├── control-structures.md
├── exceptions.md
├── functions.md
├── globals.md
├── installation.md
├── introduction.md
├── language.md
├── license.md
├── lifecycle.md
├── motivation.md
├── oop.md
├── operator-precedence.md
├── operators.md
├── optimizations.md
├── optimizers.md
├── phpinfo.md
├── right-menu.json
├── sidebar.json
├── static-analysis.md
├── tutorial.md
├── types.md
├── warnings.md
└── welcome.md
├── es-es
├── arrays.md
├── builtin-methods.md
├── closures.md
├── command-line.md
├── config.md
├── control-structures.md
├── exceptions.md
├── functions.md
├── globals.md
├── installation.md
├── introduction.md
├── language.md
├── license.md
├── lifecycle.md
├── motivation.md
├── oop.md
├── operator-precedence.md
├── operators.md
├── optimizations.md
├── optimizers.md
├── phpinfo.md
├── right-menu.json
├── sidebar.json
├── static-analysis.md
├── tutorial.md
├── types.md
├── warnings.md
└── welcome.md
├── ru-ru
├── arrays.md
├── builtin-methods.md
├── closures.md
├── command-line.md
├── config.md
├── control-structures.md
├── exceptions.md
├── functions.md
├── globals.md
├── installation.md
├── introduction.md
├── language.md
├── license.md
├── lifecycle.md
├── motivation.md
├── oop.md
├── operator-precedence.md
├── operators.md
├── optimizations.md
├── optimizers.md
├── phpinfo.md
├── right-menu.json
├── sidebar.json
├── static-analysis.md
├── tutorial.md
├── types.md
├── warnings.md
└── welcome.md
├── tr-tr
├── arrays.md
├── builtin-methods.md
├── closures.md
├── command-line.md
├── config.md
├── control-structures.md
├── exceptions.md
├── functions.md
├── globals.md
├── installation.md
├── introduction.md
├── language.md
├── license.md
├── lifecycle.md
├── motivation.md
├── oop.md
├── operator-precedence.md
├── operators.md
├── optimizations.md
├── optimizers.md
├── phpinfo.md
├── right-menu.json
├── sidebar.json
├── static-analysis.md
├── tutorial.md
├── types.md
├── warnings.md
└── welcome.md
├── uk-ua
├── arrays.md
├── builtin-methods.md
├── closures.md
├── command-line.md
├── config.md
├── control-structures.md
├── exceptions.md
├── functions.md
├── globals.md
├── installation.md
├── introduction.md
├── language.md
├── license.md
├── lifecycle.md
├── motivation.md
├── oop.md
├── operator-precedence.md
├── operators.md
├── optimizations.md
├── optimizers.md
├── phpinfo.md
├── right-menu.json
├── sidebar.json
├── static-analysis.md
├── tutorial.md
├── types.md
├── warnings.md
└── welcome.md
└── zh-cn
├── arrays.md
├── builtin-methods.md
├── closures.md
├── command-line.md
├── config.md
├── control-structures.md
├── exceptions.md
├── functions.md
├── globals.md
├── installation.md
├── introduction.md
├── language.md
├── license.md
├── lifecycle.md
├── motivation.md
├── oop.md
├── operator-precedence.md
├── operators.md
├── optimizations.md
├── optimizers.md
├── phpinfo.md
├── right-menu.json
├── sidebar.json
├── static-analysis.md
├── tutorial.md
├── types.md
├── warnings.md
└── welcome.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea/
3 | nbproject/
4 | */_build/doctrees/
5 | */_build/html/
6 | */_build/latex/*
7 | !*/_build/latex/ZephirDocumentation.pdf
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Zephir Documentation
2 |
3 | [](https://crowdin.com/project/zephir-documentation)
4 |
5 |
6 | ## Welcome
7 | This repository the documentation for the [Zephir Language](https://zephir-lang.com). The documentation can be found [here](https://docs.zephir-lang.com)
8 |
9 | ## Changes/Corrections
10 | If you see any problems in the documentation, feel free to issue a Pull Request.
11 |
12 | Pull requests are only accepted in the source language which is English `en`
13 |
14 | ## Localization
15 | We welcome contributions in localizing the documentation. Our localization is handled by our friends at [Crowdin](https://crowdin.com), who very generously offered their platform for our project.
16 |
17 | You can visit [the project in Crowdin](https://crowdin.com/project/zephir-documentation) and start translating there. Crowdin will issue pull requests to this repository automatically when new translations come in and we manually update the website that hosts our documents.
--------------------------------------------------------------------------------
/crowdin.yml:
--------------------------------------------------------------------------------
1 | files:
2 | - source: /en/*.md
3 | translation: /%locale%/%original_file_name%
4 | - source: /en/*.json
5 | translation: /%locale%/%original_file_name%
6 |
--------------------------------------------------------------------------------
/el-gr/arrays.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Πίνακες
8 |
9 | Array manipulation in Zephir provides a way to use PHP [array](https://www.php.net/manual/en/language.types.array.php). An array is an implementation of a [hash table](https://en.wikipedia.org/wiki/Hash_table).
10 |
11 |
12 |
13 | ## Declaring Array Variables
14 |
15 | Array variables can be declared using the keywords 'var' or 'array':
16 |
17 | ```zephir
18 | var a = []; // array variable, its type can be changed
19 | array b = []; // array variable, its type cannot be changed across execution
20 | ```
21 |
22 |
23 |
24 | ## Creating Arrays
25 |
26 | An array is created by enclosing its elements in square brackets:
27 |
28 | ##### Creating an empty array
29 |
30 | ```zephir
31 | let elements = [];
32 | ```
33 |
34 | ##### Creating an array with elements
35 |
36 | ```zephir
37 | let elements = [1, 3, 4];
38 | ```
39 |
40 | ##### Creating an array with elements of different types
41 |
42 | ```zephir
43 | let elements = ["first", 2, true];
44 | ```
45 |
46 | ##### A multidimensional array
47 |
48 | ```zephir
49 | let elements = [[0, 1], [4, 5], [2, 3]];
50 | ```
51 |
52 | As PHP, hashes or dictionaries are supported:
53 |
54 | ##### Creating a hash with string keys
55 |
56 | ```zephir
57 | let elements = ["foo": "bar", "bar": "foo"];
58 | ```
59 |
60 | ##### Creating a hash with numeric keys
61 |
62 | ```zephir
63 | let elements = [4: "bar", 8: "foo"];
64 | ```
65 |
66 | ##### Creating a hash with mixed string and numeric keys
67 |
68 | ```zephir
69 | let elements = [4: "bar", "foo": 8];
70 | ```
71 |
72 |
73 |
74 | ## Updating arrays
75 |
76 | Arrays are updated in the same way as PHP, using square brackets:
77 |
78 | ##### Updating an array with a string key
79 |
80 | ```zephir
81 | let elements["foo"] = "bar";
82 | ```
83 |
84 | ##### Updating an array with a numeric key
85 |
86 | ```zephir
87 | let elements[0] = "bar";
88 | ```
89 |
90 | ##### Updating multi-dimensional array
91 |
92 | ```zephir
93 | let elements[0]["foo"] = "bar";
94 | let elements["foo"][0] = "bar";
95 | ```
96 |
97 |
98 |
99 | ## Appending elements
100 |
101 | Elements can be appended at the end of the array as follows:
102 |
103 | ##### Append an element to the array
104 |
105 | ```zephir
106 | let elements[] = "bar";
107 | ```
108 |
109 |
110 |
111 | ## Reading elements from arrays
112 |
113 | It is possible to read array elements as follows:
114 |
115 | ##### Getting an element using the string key `foo`
116 |
117 | ```zephir
118 | let foo = elements["foo"];
119 | ```
120 |
121 | ##### Getting an element using the numeric key 0
122 |
123 | ```zephir
124 | let foo = elements[0];
125 | ```
--------------------------------------------------------------------------------
/el-gr/closures.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Closures
8 |
9 | You can use closures (a.k.a. anonymous functions) in Zephir; these are PHP compatible and can be returned to the PHP userland:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Functional
15 | {
16 |
17 | public function map(array! data)
18 | {
19 | return function(number) {
20 | return number * number;
21 | };
22 | }
23 | }
24 | ```
25 |
26 | It also can be executed directly within Zephir, and passed as a parameter to other functions/methods:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Functional
32 | {
33 |
34 | public function map(array! data)
35 | {
36 | return data->map(function(number) {
37 | return number * number;
38 | });
39 | }
40 | }
41 | ```
42 |
43 | A short syntax is also available to define closures:
44 |
45 | ```zephir
46 | namespace MyLibrary;
47 |
48 | class Functional
49 | {
50 |
51 | public function map(array! data)
52 | {
53 | return data->map(number => number * number);
54 | }
55 | }
56 | ```
--------------------------------------------------------------------------------
/el-gr/command-line.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # The Zephir Command Line
8 |
9 | Once Zephir is installed, you'll use the `zephir` command to manage the Zephir compiler for your projects. This chapter, and the ones following, are about the command itself, how to use it, and how to understand the things it outputs.
10 |
11 | As of Zephir 0.11.7, the compiler makes use of `stderr` for displaying error messages. This means you can handle error outputs separately from normal ones, like so:
12 |
13 | ```bash
14 | zephir generate 2> errors.log 1> /dev/null
15 | ```
16 |
17 |
18 |
19 | ## `zephir api`
20 |
21 | Generates an HTML API based on the classes exposed in the extension
22 |
23 | - `--backend=BACKEND`: Backend used to generate HTML API (default: `ZendEngine3`)
24 | - `--path=PATH` (or `-p PATH`): The API theme to be used
25 | - `--output=OUTPUT` (or `-o OUTPUT`): Output directory to generate theme
26 | - `--options=OPTIONS`: Theme options
27 | - `--url=URL`: The base URL to be used when generating links
28 |
29 |
30 |
31 | ## `zephir build`
32 |
33 | This is a meta command that just calls the [`generate`](#zephir-generate), [`compile`](#zephir-compile), and [`install`](#zephir-install) commands. Check those commands for more information on supported options and behaviors for each.
34 |
35 |
36 |
37 | ## `zephir clean`
38 |
39 | Cleans any object files created by the extension
40 |
41 |
42 |
43 | ## `zephir compile`
44 |
45 | Compile a Zephir extension
46 |
47 | - `--backend=BACKEND`: Backend used to build extension (default: `ZendEngine3`)
48 | - `--dev`: Build the extension in development mode
49 | - `--no-dev`: Build the extension in production mode
50 |
51 | Using `--dev` option will force building and installing the extension in development mode (debug symbols and no optimizations). An extension compiled with debugging symbols means you can run a program or library through a debugger and the debugger's output will be user friendlier. These debugging symbols also enlarge the program or library significantly.
52 |
53 | NOTE: Zephir development mode will be enabled silently if your PHP binary was compiled in a debug configuration.
54 |
55 | In some cases, we would like to get production ready extension even if the PHP binary was compiled in a debug configuration. Use `--no-dev` option to achieve this behavior.
56 |
57 | Additionally, any of the options available [under `extra` in the configuration file](/{{ page.version }}/{{ page.language }}/config#extra) can also be passed as options, here, such as `--export-classes` and `--indent=tabs`.
58 |
59 |
60 |
61 | ## `zephir fullclean`
62 |
63 | Cleans any object files created by the extension (including files generated by phpize)
64 |
65 |
66 |
67 | ## `zephir generate`
68 |
69 | Generates C code from the Zephir code
70 |
71 | - `--backend=BACKEND`: Backend used to build extension (default: `ZendEngine3`)
72 |
73 |
74 |
75 | ## `zephir help`
76 |
77 | Displays help for a command
78 |
79 |
80 |
81 | ## `zephir init`
82 |
83 | Initializes a Zephir extension `zephir init `
84 |
85 | - `namespace`: The extension namespace
86 | - `--backend=BACKEND`: Backend used to create extension (default: `ZendEngine3`)
87 |
88 |
89 |
90 | ## `zephir install`
91 |
92 | Installs the extension in the extension directory (may require root password)
93 |
94 | - `--dev`: Install the extension in development mode
95 | - `--no-dev`: Install the extension in production mode
96 |
97 |
98 |
99 | ## `zephir list`
100 |
101 | Lists commands
102 |
103 |
104 |
105 | ## `zephir stubs`
106 |
107 | Generates stubs that can be used in a PHP IDE
108 |
109 | - `--backend=BACKEND`: Backend used to generate stubs (default: `ZendEngine3`)
110 |
--------------------------------------------------------------------------------
/el-gr/exceptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Exceptions
8 |
9 | Zephir implements exceptions at a very low level, providing similar behavior and functionality to PHP.
10 |
11 | When an exception is thrown, a `catch` block can be used to capture the exception and allow the developer to provide proper handling:
12 |
13 | Exceptions can be thrown inside the `try` block. Handling happens in the `catch` block, exactly as in PHP:
14 |
15 | ```zephir
16 | var e;
17 | try {
18 |
19 | throw new \Exception("This is an exception");
20 |
21 | } catch \Exception, e {
22 |
23 | echo e->getMessage();
24 | }
25 | ```
26 |
27 | Zephir also provides a "silent" `try` block, that simply ignores any exceptions produced within that block:
28 |
29 | ```zephir
30 | try {
31 | throw new \Exception("This is an exception");
32 | }
33 | ```
34 |
35 | If you don't need an exception variable when 'catch'ing, then you can safely not provide it:
36 |
37 | ```zephir
38 | try {
39 |
40 | throw new \Exception("This is an exception");
41 |
42 | } catch \Exception {
43 |
44 | echo "An exception occur!";
45 | }
46 | ```
47 |
48 | A single `catch` block can be used to catch multiple types of exception:
49 |
50 | ```zephir
51 | var e;
52 | try {
53 |
54 | throw new \Exception("This is an exception");
55 |
56 | } catch \RuntimeException|\Exception, e {
57 |
58 | echo e->getMessage();
59 | }
60 | ```
61 |
62 | Zephir allows you to throw literals or static typed variables as if they were the message of the exception:
63 |
64 | ```zephir
65 | // throw new \Exception("Test");
66 | throw "Test";
67 |
68 | // throw new \Exception((string) 't');
69 | throw 't';
70 |
71 | // throw new \Exception((string) 123);
72 | throw 123;
73 |
74 | // throw new \Exception((string) 123.123);
75 | throw 123.123;
76 | ```
77 |
78 | Zephir's exceptions provide the same methods to know where the exception happened that PHP's exceptions do. That is, `Exception::getFile()` and `Exception::getLine()` return the location in the Zephir code where the exception was thrown:
79 |
80 | ```bash
81 | Exception: The static method 'someMethod' does not exist on model 'Robots'
82 | File=phalcon/mvc/model.zep Line=4042
83 | #0 /home/scott/test.php(64): Phalcon\Mvc\Model::__callStatic('someMethod', Array)
84 | #1 /home/scott/test.php(64): Robots::someMethod()
85 | #2 {main}
86 | ```
--------------------------------------------------------------------------------
/el-gr/functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Calling Functions
8 |
9 | PHP has a rich library of functions that you can use within your extensions. To call a PHP function you simply use it as normal within your Zephir code:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Encoder
15 | {
16 | public function encode(var text)
17 | {
18 | if strlen(text) != 0 {
19 | return base64_encode(text);
20 | }
21 | return false;
22 | }
23 | }
24 | ```
25 |
26 | You can also call functions that are expected to exist in the PHP userland, but are not necessarily built in to PHP itself:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Encoder
32 | {
33 |
34 | public function encode(var text)
35 | {
36 | if strlen(text) != 0 {
37 | if function_exists("my_custom_encoder") {
38 | return my_custom_encoder(text);
39 | } else {
40 | return base64_encode(text);
41 | }
42 | }
43 | return false;
44 | }
45 | }
46 | ```
47 |
48 | Note that all PHP functions only receive and return dynamic variables. If you pass a static typed variable as a parameter, a temporary dynamic variable will automatically be used as a bridge in order to call the function:
49 |
50 | ```zephir
51 | namespace MyLibrary;
52 |
53 | class Encoder
54 | {
55 | public function encode(string text)
56 | {
57 | if strlen(text) != 0 {
58 | // an implicit dynamic variable is created to
59 | // pass the static typed 'text' as parameter
60 | return base64_encode(text);
61 | }
62 | return false;
63 | }
64 | }
65 | ```
66 |
67 | Similarly, functions return dynamic values, which cannot be directly assigned to static variables without the appropriate explicit cast:
68 |
69 | ```zephir
70 | namespace MyLibrary;
71 |
72 | class Encoder
73 | {
74 | public function encode(string text)
75 | {
76 | string encoded = "";
77 |
78 | if strlen(text) != 0 {
79 | let encoded = (string) base64_encode(text);
80 | return "(" . encoded . ")";
81 | }
82 | return false;
83 | }
84 | }
85 | ```
86 |
87 | Zephir also provides a way for you to call functions dynamically, such as:
88 |
89 | ```zephir
90 | namespace MyLibrary;
91 |
92 | class Encoder
93 | {
94 | public function encode(var callback, string text)
95 | {
96 | return {callback}(text);
97 | }
98 | }
99 | ```
--------------------------------------------------------------------------------
/el-gr/globals.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Extension Globals
8 |
9 | PHP extensions provide a way to define globals within an extension. Reading/writing globals should be faster than any other global mechanisms (like static members). You can use extension globals to set up configuration options that change the behavior of your library.
10 |
11 | In Zephir, extension globals are restricted to simple scalar types like `int`/`bool`/`double`/`char`, etc. Complex types such as string/array/object/resource are not allowed here.
12 |
13 | You can enable extension globals by adding the following structure to your `config.json`:
14 |
15 | ```json
16 | {
17 | "globals": {
18 | "allow_some_feature": {
19 | "type": "bool",
20 | "default": true,
21 | "module": true
22 | },
23 | "number_times": {
24 | "type": "int",
25 | "default": 10
26 | },
27 | "some_component.my_setting_1": {
28 | "type": "bool",
29 | "default": true
30 | },
31 | "some_component.my_setting_2": {
32 | "type": "int",
33 | "default": 100
34 | }
35 | }
36 | }
37 | ```
38 |
39 | Each global has the following structure:
40 |
41 | ```json
42 | "": {
43 | "type": "",
44 | "default":
45 | }
46 | ```
47 |
48 | Compound (namespaced) globals have the following structure:
49 |
50 | ```json
51 | ".": {
52 | "type": "",
53 | "default":
54 | }
55 | ```
56 |
57 | The optional `module` key, if present, places that global's initialization process into the module-wide `GINIT` lifecycle event, which just means it will only be set up once per PHP process, rather than being reinitialized for every request, which is the default:
58 |
59 | ```json
60 | {
61 | "globals": {
62 | "allow_some_feature": {
63 | "type": "bool",
64 | "default": true,
65 | "module": true
66 | },
67 | "number_times": {
68 | "type": "int",
69 | "default": 10
70 | }
71 | }
72 | }
73 | ```
74 |
75 | In the example above, `allow_some_feature` is set up only once at startup; `number_times` is set up at the start of each request.
76 |
77 | Inside any method, you can read/write extension globals using the built-in functions `globals_get`/`globals_set`:
78 |
79 | ```zephir
80 | globals_set("allow_some_feature", true);
81 | let someFeature = globals_get("allow_some_feature");
82 | ```
83 |
84 | If you want to change these globals from PHP, a good option is include a method aimed at this:
85 |
86 | ```zephir
87 | namespace Test;
88 |
89 | class MyOptions
90 | {
91 |
92 | public static function setOptions(array options)
93 | {
94 | boolean someOption, anotherOption;
95 |
96 | if fetch someOption, options["some_option"] {
97 | globals_set("some_option", someOption);
98 | }
99 |
100 | if fetch anotherOption, options["another_option"] {
101 | globals_set("another_option", anotherOption);
102 | }
103 | }
104 | }
105 | ```
106 |
107 | Extension globals cannot be dynamically accessed, since the C code generated by the `globals_get`/`globals_set` optimizers must be resolved at compilation time:
108 |
109 | ```zephir
110 | let myOption = "someOption";
111 |
112 | // will throw a compiler exception
113 | let someOption = globals_get(myOption);
114 | ```
--------------------------------------------------------------------------------
/el-gr/license.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # License
8 |
9 | MIT License
10 |
11 | Copyright (c) 2013-present Zephir Team
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/el-gr/operator-precedence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Operator Precedence
8 | **Operator precedence** determines how operators are parsed. Operators with higher precedence become the operands of operators with lower precedence. For example, in the expression `1 + 5 * 3`, the answer is 16 and not 18 because the multiplication (`*`) operator has a higher precedence than the addition (`+`) operator. Parentheses may be used to force precedence, if necessary. For instance: `(1 + 5) * 3` evaluates to 18.
9 |
10 |
11 |
12 | ## Associativity
13 | When operators have equal precedence their **associativity** determines how the operators are grouped. For example `-` is _left-associative_, so `1 - 2 - 3` is grouped as `(1 - 2) - 3` and evaluates to `-4`. `=` on the other hand is _right-associative_, so `let a = b = c` is grouped as `let a = (b = c)`.
14 |
15 | Operators of equal precedence that are _non-associative_ cannot be used next to one another. For example:
16 | ```zep
17 | new new Foo();
18 | ```
19 | is illegal in Zephir, because the `new` is non-associative. At the moment, `new` is the only non-associative operator in Zephir.
20 |
21 | Use of parentheses, even when not strictly necessary, can often increase readability of the code, by making grouping explicit, rather than relying on the implicit operator precedence and associativity.
22 |
23 |
24 |
25 | ## Precedence Table
26 | The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides grouping.
27 |
28 | | Precedence | Operators | Operator type | Associativity |
29 | | ---------- | -------------------------------- | ----------------------------------- | --------------- |
30 | | 1 | `->` | Member Access | right-to-left |
31 | | 2 | `~` | Bitwise NOT | right-to-left |
32 | | 3 | `!` | Logical NOT | right-to-left |
33 | | 4 | `new` | new | non-associative |
34 | | 5 | `clone` | clone | right-to-left |
35 | | 6 | `typeof` | Type-of | right-to-left |
36 | | 7 | `..`, `...` | Inclusive/exclusive range | left-to-right |
37 | | 8 | `isset`, `fetch`, `empty` | Exclusive range | right-to-left |
38 | | 9 | `*`, `/`, `%` | Multiplication, Division, Remainder | left-to-right |
39 | | 10 | `+`, `-`, `.` | Addition, Subtraction, Concat | left-to-right |
40 | | 11 | `<<`, `>>` | Bitwise shift left/right | left-to-right |
41 | | 12 | `<`, `<=`, `=>`, `>` | Comparison | left-to-right |
42 | | 13 | `==`, `!==`, `===`, `!==` | Comparison | left-to-right |
43 | | 14 | `&` | Bitwise AND, references | left-to-right |
44 | | 15 | `^` | Bitwise XOR | left-to-right |
45 | | 16 | `|` | Bitwise OR | left-to-right |
46 | | 17 | `instanceof` | Instance-of | left-to-right |
47 | | 18 | `&&` | Logical AND | left-to-right |
48 | | 19 | `||` | Logical OR | left-to-right |
49 | | 20 | `likely`, `unlikely` | Branch prediction | right-to-left |
50 | | 21 | `?` | Logical | right-to-left |
51 | | 21 | `=>` | Closure Arrow | right-to-left |
52 |
--------------------------------------------------------------------------------
/el-gr/phpinfo.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Phpinfo() sections
8 |
9 | Like most extensions, Zephir extensions are able to show information in the [phpinfo()](https://php.net/manual/en/function.phpinfo.php) output. This information is usually related to directives, environment data, etc.
10 |
11 | By default, every Zephir extension automatically adds a basic table to the `phpinfo()` output showing the extension version, and any INI options the extension supports.
12 |
13 | You can add more directives by adding the following configuration to the `config.json` file:
14 |
15 | ```json
16 | "info": [
17 | {
18 | "header": ["Directive", "Value"],
19 | "rows": [
20 | ["setting1", "value1"],
21 | ["setting2", "value2"]
22 | ]
23 | },
24 | {
25 | "header": ["Directive", "Value"],
26 | "rows": [
27 | ["setting3", "value3"],
28 | ["setting4", "value4"]
29 | ]
30 | }
31 | ]
32 | ```
33 |
34 | This information will be shown as follows:
35 |
36 | 
--------------------------------------------------------------------------------
/el-gr/sidebar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Welcome",
4 | "url": "welcome"
5 | },
6 | {
7 | "text": "Why Zephir",
8 | "url": "motivation"
9 | },
10 | {
11 | "text": "Introducing Zephir",
12 | "url": "introduction"
13 | },
14 | {
15 | "text": "Installation",
16 | "url": "installation"
17 | },
18 | {
19 | "text": "Tutorial",
20 | "url": "tutorial"
21 | },
22 | {
23 | "text": "Basic Syntax",
24 | "url": "language"
25 | },
26 | {
27 | "text": "Types",
28 | "url": "types"
29 | },
30 | {
31 | "text": "Operators",
32 | "url": "operators"
33 | },
34 | {
35 | "text": "Operator Precedence",
36 | "url": "operator-precedence"
37 | },
38 | {
39 | "text": "Πίνακες",
40 | "url": "arrays"
41 | },
42 | {
43 | "text": "Classes and objects",
44 | "url": "oop"
45 | },
46 | {
47 | "text": "Built-in methods",
48 | "url": "builtin-methods"
49 | },
50 | {
51 | "text": "Control structures",
52 | "url": "control-structures"
53 | },
54 | {
55 | "text": "Exceptions",
56 | "url": "exceptions"
57 | },
58 | {
59 | "text": "Calling functions",
60 | "url": "functions"
61 | },
62 | {
63 | "text": "Closures",
64 | "url": "closures"
65 | },
66 | {
67 | "text": "Custom optimizers",
68 | "url": "optimizers"
69 | },
70 | {
71 | "text": "Configuration file",
72 | "url": "config"
73 | },
74 | {
75 | "text": "Command Line",
76 | "url": "command-line"
77 | },
78 | {
79 | "text": "Lifecycle hooks",
80 | "url": "lifecycle"
81 | },
82 | {
83 | "text": "Extension globals",
84 | "url": "globals"
85 | },
86 | {
87 | "text": "phpinfo() sections",
88 | "url": "phpinfo"
89 | },
90 | {
91 | "text": "Static analysis",
92 | "url": "static-analysis"
93 | },
94 | {
95 | "text": "Optimizations",
96 | "url": "optimizations"
97 | },
98 | {
99 | "text": "Compiler warnings",
100 | "url": "warnings"
101 | },
102 | {
103 | "text": "License",
104 | "url": "license"
105 | }
106 | ]
107 |
--------------------------------------------------------------------------------
/el-gr/static-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Static Analysis
8 |
9 | Zephir's compiler provides static analysis of the compiled code. The idea behind this feature is to help the developer to find potential problems and avoid unexpected behaviors, well before runtime.
10 |
11 |
12 |
13 | ## Conditional Unassigned Variables
14 |
15 | Static Analysis of assignments tries to identify if a variable is used before it's assigned:
16 |
17 | ```zephir
18 | class Utils
19 | {
20 | public function someMethod(b)
21 | {
22 | string a; char c;
23 |
24 | if b == 10 {
25 | let a = "hello";
26 | }
27 |
28 | //a could be unitialized here
29 | for c in a {
30 | echo c, PHP_EOL;
31 | }
32 | }
33 | }
34 | ```
35 |
36 | The above example illustrates a common situation. The variable `a` is assigned only when `b` is equal to 10, then it's required to use the value of this variable - but it could be uninitialized. Zephir detects this, automatically initializes the variable to an empty string, and generates a warning alerting the developer:
37 |
38 | ```bash
39 | Warning: Variable 'a' was assigned for the first time in conditional branch,
40 | consider initialize it in its declaration in
41 | /home/scott/test/test/utils.zep on 21 [conditional-initialization]
42 |
43 | for c in a {
44 | ```
45 |
46 | Finding such errors is sometimes tricky, however static analysis helps the programmer to find bugs in advance.
47 |
48 |
49 |
50 | ## Dead Code Elimination
51 |
52 | Zephir informs the developer about unreachable branches in the code and performs dead code elimination, which means it gets rid of all that code from the generated binary, since it cannot be executed anyway:
53 |
54 | ```zephir
55 | class Utils
56 | {
57 | public function someMethod(b)
58 | {
59 | if false {
60 | // This is never executed
61 | echo "hello";
62 | }
63 | }
64 | }
65 | ```
--------------------------------------------------------------------------------
/el-gr/welcome.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'el-gr'
4 | version: '0.12'
5 | ---
6 |
7 | # Καλώς ορίσατε!
8 |
9 | Welcome to Zephir, an open source, high-level/domain specific language designed to ease the creation and maintainability of extensions for PHP, with a focus on type and memory safety.
10 |
11 |
12 |
13 | ## Μερικά χαρακτηριστικά γνωρίσματα
14 |
15 | Κύρια χαρακτηριστικά της Zephir είναι:
16 |
17 | | Χαρακτηριστικό | Description |
18 | | ----------------- | ---------------------------------------------------- |
19 | | Type system | dynamic/static |
20 | | Memory safety | pointers or direct memory management are not allowed |
21 | | Compilation model | ahead of time |
22 | | Memory model | task-local garbage collection |
23 |
24 |
25 |
26 | ## Μια μικρή γεύση
27 |
28 | The following code registers a class with a method that filters variables, returning their alphabetic characters:
29 |
30 | ```zephir
31 | namespace MyLibrary;
32 |
33 | /**
34 | * Filter
35 | */
36 | class Filter
37 | {
38 | /**
39 | * Filters a string, returning its alpha charactersa
40 | *
41 | * @param string str
42 | */
43 | public function alpha(string str)
44 | {
45 | char ch; string filtered = "";
46 |
47 | for ch in str {
48 | if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
49 | let filtered .= ch;
50 | }
51 | }
52 |
53 | return filtered;
54 | }
55 | }
56 | ```
57 |
58 | The class can be used from PHP as follows:
59 |
60 | ```php
61 | alpha("01he#l.lo?/1"); // prints hello
65 | ```
66 |
67 |
68 |
69 | ## External Links
70 |
71 | Below we have collected links to external resources that may interest you:
72 |
73 | - [Type system](https://en.wikipedia.org/wiki/Type_system)
74 | - [Memory safety](https://en.wikipedia.org/wiki/Memory_safety)
75 | - [Ahead-of-time compilation](https://en.wikipedia.org/wiki/Ahead-of-time_compilation)
76 | - [Memory management](https://en.wikipedia.org/wiki/Memory_management)
--------------------------------------------------------------------------------
/en/arrays.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Arrays
8 | Array manipulation in Zephir provides a way to use PHP [array](https://www.php.net/manual/en/language.types.array.php). An array is an implementation of a [hash table](https://en.wikipedia.org/wiki/Hash_table).
9 |
10 |
11 | ## Declaring Array Variables
12 | Array variables can be declared using the keywords 'var' or 'array':
13 |
14 | ```zephir
15 | var a = []; // array variable, its type can be changed
16 | array b = []; // array variable, its type cannot be changed across execution
17 | ```
18 |
19 |
20 | ## Creating Arrays
21 | An array is created by enclosing its elements in square brackets:
22 |
23 | ##### Creating an empty array
24 |
25 | ```zephir
26 | let elements = [];
27 | ```
28 |
29 | ##### Creating an array with elements
30 |
31 | ```zephir
32 | let elements = [1, 3, 4];
33 | ```
34 |
35 | ##### Creating an array with elements of different types
36 |
37 | ```zephir
38 | let elements = ["first", 2, true];
39 | ```
40 |
41 | ##### A multidimensional array
42 |
43 | ```zephir
44 | let elements = [[0, 1], [4, 5], [2, 3]];
45 | ```
46 |
47 | As PHP, hashes or dictionaries are supported:
48 |
49 | ##### Creating a hash with string keys
50 |
51 | ```zephir
52 | let elements = ["foo": "bar", "bar": "foo"];
53 | ```
54 |
55 | ##### Creating a hash with numeric keys
56 |
57 | ```zephir
58 | let elements = [4: "bar", 8: "foo"];
59 | ```
60 |
61 | ##### Creating a hash with mixed string and numeric keys
62 |
63 | ```zephir
64 | let elements = [4: "bar", "foo": 8];
65 | ```
66 |
67 |
68 | ## Updating arrays
69 | Arrays are updated in the same way as PHP, using square brackets:
70 |
71 | ##### Updating an array with a string key
72 |
73 | ```zephir
74 | let elements["foo"] = "bar";
75 | ```
76 |
77 | ##### Updating an array with a numeric key
78 |
79 | ```zephir
80 | let elements[0] = "bar";
81 | ```
82 |
83 | ##### Updating multi-dimensional array
84 |
85 | ```zephir
86 | let elements[0]["foo"] = "bar";
87 | let elements["foo"][0] = "bar";
88 | ```
89 |
90 |
91 | ## Appending elements
92 | Elements can be appended at the end of the array as follows:
93 |
94 | ##### Append an element to the array
95 |
96 | ```zephir
97 | let elements[] = "bar";
98 | ```
99 |
100 |
101 | ## Reading elements from arrays
102 | It is possible to read array elements as follows:
103 |
104 | ##### Getting an element using the string key `foo`
105 |
106 | ```zephir
107 | let foo = elements["foo"];
108 | ```
109 |
110 | ##### Getting an element using the numeric key 0
111 |
112 | ```zephir
113 | let foo = elements[0];
114 | ```
115 |
--------------------------------------------------------------------------------
/en/closures.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Closures
8 | You can use closures (a.k.a. anonymous functions) in Zephir; these are PHP compatible and can be returned to the PHP userland:
9 |
10 | ```zephir
11 | namespace MyLibrary;
12 |
13 | class Functional
14 | {
15 |
16 | public function map(array! data)
17 | {
18 | return function(number) {
19 | return number * number;
20 | };
21 | }
22 | }
23 | ```
24 |
25 | It also can be executed directly within Zephir, and passed as a parameter to other functions/methods:
26 |
27 | ```zephir
28 | namespace MyLibrary;
29 |
30 | class Functional
31 | {
32 |
33 | public function map(array! data)
34 | {
35 | return data->map(function(number) {
36 | return number * number;
37 | });
38 | }
39 | }
40 | ```
41 |
42 | A short syntax is also available to define closures:
43 |
44 | ```zephir
45 | namespace MyLibrary;
46 |
47 | class Functional
48 | {
49 |
50 | public function map(array! data)
51 | {
52 | return data->map(number => number * number);
53 | }
54 | }
55 | ```
56 |
--------------------------------------------------------------------------------
/en/command-line.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # The Zephir Command Line
8 |
9 | Once Zephir is installed, you'll use the `zephir` command to manage the Zephir compiler
10 | for your projects. This chapter, and the ones following, are about the command itself, how
11 | to use it, and how to understand the things it outputs.
12 |
13 | As of Zephir 0.11.7, the compiler makes use of `stderr` for displaying error messages.
14 | This means you can handle error outputs separately from normal ones, like so:
15 |
16 | ```bash
17 | zephir generate 2> errors.log 1> /dev/null
18 | ```
19 |
20 |
21 | ## `zephir api`
22 |
23 | Generates an HTML API based on the classes exposed in the extension
24 |
25 | - `--backend=BACKEND`: Backend used to generate HTML API (default: `ZendEngine3`)
26 | - `--path=PATH` (or `-p PATH`): The API theme to be used
27 | - `--output=OUTPUT` (or `-o OUTPUT`): Output directory to generate theme
28 | - `--options=OPTIONS`: Theme options
29 | - `--url=URL`: The base URL to be used when generating links
30 |
31 |
32 | ## `zephir build`
33 |
34 | This is a meta command that just calls the [`generate`](#zephir-generate), [`compile`](#zephir-compile), and [`install`](#zephir-install) commands.
35 | Check those commands for more information on supported options and behaviors for each.
36 |
37 |
38 | ## `zephir clean`
39 |
40 | Cleans any object files created by the extension
41 |
42 |
43 | ## `zephir compile`
44 |
45 | Compile a Zephir extension
46 |
47 | - `--backend=BACKEND`: Backend used to build extension (default: `ZendEngine3`)
48 | - `--dev`: Build the extension in development mode
49 | - `--no-dev`: Build the extension in production mode
50 |
51 | Using `--dev` option will force building and installing the extension in development mode
52 | (debug symbols and no optimizations). An extension compiled with debugging symbols means
53 | you can run a program or library through a debugger and the debugger's output will be user
54 | friendlier. These debugging symbols also enlarge the program or library significantly.
55 |
56 | NOTE: Zephir development mode will be enabled silently if your PHP binary was compiled in
57 | a debug configuration.
58 |
59 | In some cases, we would like to get production ready extension even if the PHP binary was
60 | compiled in a debug configuration. Use `--no-dev` option to achieve this behavior.
61 |
62 | Additionally, any of the options available [under `extra` in the configuration
63 | file](/{{ page.version }}/{{ page.language }}/config#extra) can also be passed as options, here, such as
64 | `--export-classes` and `--indent=tabs`.
65 |
66 |
67 | ## `zephir fullclean`
68 |
69 | Cleans any object files created by the extension (including files generated by phpize)
70 |
71 |
72 | ## `zephir generate`
73 |
74 | Generates C code from the Zephir code
75 |
76 | - `--backend=BACKEND`: Backend used to build extension (default: `ZendEngine3`)
77 |
78 |
79 | ## `zephir help`
80 |
81 | Displays help for a command
82 |
83 |
84 | ## `zephir init`
85 |
86 | Initializes a Zephir extension
87 | `zephir init `
88 |
89 | - `namespace`: The extension namespace
90 | - `--backend=BACKEND`: Backend used to create extension (default: `ZendEngine3`)
91 |
92 |
93 | ## `zephir install`
94 |
95 | Installs the extension in the extension directory (may require root password)
96 |
97 | - `--dev`: Install the extension in development mode
98 | - `--no-dev`: Install the extension in production mode
99 |
100 |
101 | ## `zephir list`
102 |
103 | Lists commands
104 |
105 |
106 | ## `zephir stubs`
107 |
108 | Generates stubs that can be used in a PHP IDE
109 |
110 | - `--backend=BACKEND`: Backend used to generate stubs (default: `ZendEngine3`)
111 |
--------------------------------------------------------------------------------
/en/exceptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Exceptions
8 | Zephir implements exceptions at a very low level, providing similar behavior and functionality to PHP.
9 |
10 | When an exception is thrown, a `catch` block can be used to capture the exception and allow the developer to provide proper handling:
11 |
12 | Exceptions can be thrown inside the `try` block. Handling happens in the `catch` block, exactly as in PHP:
13 |
14 | ```zephir
15 | var e;
16 | try {
17 |
18 | throw new \Exception("This is an exception");
19 |
20 | } catch \Exception, e {
21 |
22 | echo e->getMessage();
23 | }
24 | ```
25 |
26 | Zephir also provides a "silent" `try` block, that simply ignores any exceptions produced within that block:
27 |
28 | ```zephir
29 | try {
30 | throw new \Exception("This is an exception");
31 | }
32 | ```
33 |
34 | If you don't need an exception variable when 'catch'ing, then you can safely not provide it:
35 |
36 | ```zephir
37 | try {
38 |
39 | throw new \Exception("This is an exception");
40 |
41 | } catch \Exception {
42 |
43 | echo "An exception occur!";
44 | }
45 | ```
46 |
47 | A single `catch` block can be used to catch multiple types of exception:
48 |
49 | ```zephir
50 | var e;
51 | try {
52 |
53 | throw new \Exception("This is an exception");
54 |
55 | } catch \RuntimeException|\Exception, e {
56 |
57 | echo e->getMessage();
58 | }
59 | ```
60 |
61 | Zephir allows you to throw literals or static typed variables as if they were the message of the exception:
62 |
63 | ```zephir
64 | // throw new \Exception("Test");
65 | throw "Test";
66 |
67 | // throw new \Exception((string) 't');
68 | throw 't';
69 |
70 | // throw new \Exception((string) 123);
71 | throw 123;
72 |
73 | // throw new \Exception((string) 123.123);
74 | throw 123.123;
75 | ```
76 |
77 | Zephir's exceptions provide the same methods to know where the exception happened that PHP's exceptions do. That is, `Exception::getFile()` and `Exception::getLine()` return the location in the Zephir code where the exception was thrown:
78 |
79 | ```bash
80 | Exception: The static method 'someMethod' does not exist on model 'Robots'
81 | File=phalcon/mvc/model.zep Line=4042
82 | #0 /home/scott/test.php(64): Phalcon\Mvc\Model::__callStatic('someMethod', Array)
83 | #1 /home/scott/test.php(64): Robots::someMethod()
84 | #2 {main}
85 | ```
86 |
--------------------------------------------------------------------------------
/en/functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Calling Functions
8 | PHP has a rich library of functions that you can use within your extensions. To call a PHP function you simply use it as normal within your Zephir code:
9 |
10 | ```zephir
11 | namespace MyLibrary;
12 |
13 | class Encoder
14 | {
15 | public function encode(var text)
16 | {
17 | if strlen(text) != 0 {
18 | return base64_encode(text);
19 | }
20 | return false;
21 | }
22 | }
23 | ```
24 |
25 | You can also call functions that are expected to exist in the PHP userland, but are not necessarily built in to PHP itself:
26 |
27 | ```zephir
28 | namespace MyLibrary;
29 |
30 | class Encoder
31 | {
32 |
33 | public function encode(var text)
34 | {
35 | if strlen(text) != 0 {
36 | if function_exists("my_custom_encoder") {
37 | return my_custom_encoder(text);
38 | } else {
39 | return base64_encode(text);
40 | }
41 | }
42 | return false;
43 | }
44 | }
45 | ```
46 |
47 | Note that all PHP functions only receive and return dynamic variables. If you pass a static typed variable as a parameter, a temporary dynamic variable will automatically be used as a bridge in order to call the function:
48 |
49 | ```zephir
50 | namespace MyLibrary;
51 |
52 | class Encoder
53 | {
54 | public function encode(string text)
55 | {
56 | if strlen(text) != 0 {
57 | // an implicit dynamic variable is created to
58 | // pass the static typed 'text' as parameter
59 | return base64_encode(text);
60 | }
61 | return false;
62 | }
63 | }
64 | ```
65 |
66 | Similarly, functions return dynamic values, which cannot be directly assigned to static variables without the appropriate explicit cast:
67 |
68 | ```zephir
69 | namespace MyLibrary;
70 |
71 | class Encoder
72 | {
73 | public function encode(string text)
74 | {
75 | string encoded = "";
76 |
77 | if strlen(text) != 0 {
78 | let encoded = (string) base64_encode(text);
79 | return "(" . encoded . ")";
80 | }
81 | return false;
82 | }
83 | }
84 | ```
85 |
86 | Zephir also provides a way for you to call functions dynamically, such as:
87 |
88 | ```zephir
89 | namespace MyLibrary;
90 |
91 | class Encoder
92 | {
93 | public function encode(var callback, string text)
94 | {
95 | return {callback}(text);
96 | }
97 | }
98 | ```
99 |
--------------------------------------------------------------------------------
/en/globals.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Extension Globals
8 | PHP extensions provide a way to define globals within an extension. Reading/writing globals should be faster than any other global mechanisms (like static members). You can use extension globals to set up configuration options that change the behavior of your library.
9 |
10 | In Zephir, extension globals are restricted to simple scalar types like `int`/`bool`/`double`/`char`, etc. Complex types such as string/array/object/resource are not allowed here.
11 |
12 | You can enable extension globals by adding the following structure to your `config.json`:
13 |
14 | ```json
15 | {
16 | "globals": {
17 | "allow_some_feature": {
18 | "type": "bool",
19 | "default": true,
20 | "module": true
21 | },
22 | "number_times": {
23 | "type": "int",
24 | "default": 10
25 | },
26 | "some_component.my_setting_1": {
27 | "type": "bool",
28 | "default": true
29 | },
30 | "some_component.my_setting_2": {
31 | "type": "int",
32 | "default": 100
33 | }
34 | }
35 | }
36 | ```
37 |
38 | Each global has the following structure:
39 |
40 | ```json
41 | "": {
42 | "type": "",
43 | "default":
44 | }
45 | ```
46 |
47 | Compound (namespaced) globals have the following structure:
48 |
49 | ```json
50 | ".": {
51 | "type": "",
52 | "default":
53 | }
54 | ```
55 |
56 | The optional `module` key, if present, places that global's initialization process into the module-wide `GINIT` lifecycle event, which just means it will only be set up once per PHP process, rather than being reinitialized for every request, which is the default:
57 |
58 | ```json
59 | {
60 | "globals": {
61 | "allow_some_feature": {
62 | "type": "bool",
63 | "default": true,
64 | "module": true
65 | },
66 | "number_times": {
67 | "type": "int",
68 | "default": 10
69 | }
70 | }
71 | }
72 | ```
73 |
74 | In the example above, `allow_some_feature` is set up only once at startup; `number_times` is set up at the start of each request.
75 |
76 | Inside any method, you can read/write extension globals using the built-in functions `globals_get`/`globals_set`:
77 |
78 | ```zephir
79 | globals_set("allow_some_feature", true);
80 | let someFeature = globals_get("allow_some_feature");
81 | ```
82 |
83 | If you want to change these globals from PHP, a good option is include a method aimed at this:
84 |
85 | ```zephir
86 | namespace Test;
87 |
88 | class MyOptions
89 | {
90 |
91 | public static function setOptions(array options)
92 | {
93 | boolean someOption, anotherOption;
94 |
95 | if fetch someOption, options["some_option"] {
96 | globals_set("some_option", someOption);
97 | }
98 |
99 | if fetch anotherOption, options["another_option"] {
100 | globals_set("another_option", anotherOption);
101 | }
102 | }
103 | }
104 | ```
105 |
106 | Extension globals cannot be dynamically accessed, since the C code generated by the `globals_get`/`globals_set` optimizers must be resolved at compilation time:
107 |
108 | ```zephir
109 | let myOption = "someOption";
110 |
111 | // will throw a compiler exception
112 | let someOption = globals_get(myOption);
113 | ```
114 |
--------------------------------------------------------------------------------
/en/license.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # License
8 |
9 | MIT License
10 |
11 | Copyright (c) 2013-present Zephir Team
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy
14 | of this software and associated documentation files (the "Software"), to deal
15 | in the Software without restriction, including without limitation the rights
16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 | copies of the Software, and to permit persons to whom the Software is
18 | furnished to do so, subject to the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be included in
21 | all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 | THE SOFTWARE.
30 |
--------------------------------------------------------------------------------
/en/operator-precedence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 | # Operator Precedence
7 | **Operator precedence** determines how operators are parsed. Operators with
8 | higher precedence become the operands of operators with lower precedence. For
9 | example, in the expression `1 + 5 * 3`, the answer is 16 and not 18 because
10 | the multiplication (`*`) operator has a higher precedence than the addition
11 | (`+`) operator. Parentheses may be used to force precedence, if necessary.
12 | For instance: `(1 + 5) * 3` evaluates to 18.
13 |
14 |
15 | ## Associativity
16 | When operators have equal precedence their **associativity** determines how the
17 | operators are grouped. For example `-` is _left-associative_, so `1 - 2 - 3` is
18 | grouped as `(1 - 2) - 3` and evaluates to `-4`. `=` on the other hand is
19 | _right-associative_, so `let a = b = c` is grouped as `let a = (b = c)`.
20 |
21 | Operators of equal precedence that are _non-associative_ cannot be used next to
22 | one another. For example:
23 | ```zep
24 | new new Foo();
25 | ```
26 | is illegal in Zephir, because the `new` is non-associative. At the moment, `new`
27 | is the only non-associative operator in Zephir.
28 |
29 | Use of parentheses, even when not strictly necessary, can often increase
30 | readability of the code, by making grouping explicit, rather than relying on
31 | the implicit operator precedence and associativity.
32 |
33 |
34 | ## Precedence Table
35 | The following table lists the operators in order of precedence, with the
36 | highest-precedence ones at the top. Operators on the same line have equal
37 | precedence, in which case associativity decides grouping.
38 |
39 | | Precedence | Operators | Operator type | Associativity |
40 | |------------|---------------------------|-------------------------------------|-----------------|
41 | | 1 | `->` | Member Access | right-to-left |
42 | | 2 | `~` | Bitwise NOT | right-to-left |
43 | | 3 | `!` | Logical NOT | right-to-left |
44 | | 4 | `new` | new | non-associative |
45 | | 5 | `clone` | clone | right-to-left |
46 | | 6 | `typeof` | Type-of | right-to-left |
47 | | 7 | `..`, `...` | Inclusive/exclusive range | left-to-right |
48 | | 8 | `isset`, `fetch`, `empty` | Exclusive range | right-to-left |
49 | | 9 | `*`, `/`, `%` | Multiplication, Division, Remainder | left-to-right |
50 | | 10 | `+`, `-`, `.` | Addition, Subtraction, Concat | left-to-right |
51 | | 11 | `<<`, `>>` | Bitwise shift left/right | left-to-right |
52 | | 12 | `<`, `<=`, `=>`, `>` | Comparison | left-to-right |
53 | | 13 | `==`, `!==`, `===`, `!==` | Comparison | left-to-right |
54 | | 14 | `&` | Bitwise AND, references | left-to-right |
55 | | 15 | `^` | Bitwise XOR | left-to-right |
56 | | 16 | `|` | Bitwise OR | left-to-right |
57 | | 17 | `instanceof` | Instance-of | left-to-right |
58 | | 18 | `&&` | Logical AND | left-to-right |
59 | | 19 | `||` | Logical OR | left-to-right |
60 | | 20 | `likely`, `unlikely` | Branch prediction | right-to-left |
61 | | 21 | `?` | Logical | right-to-left |
62 | | 21 | `=>` | Closure Arrow | right-to-left |
63 |
--------------------------------------------------------------------------------
/en/phpinfo.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Phpinfo() sections
8 | Like most extensions, Zephir extensions are able to show information in the [phpinfo()](https://php.net/manual/en/function.phpinfo.php) output. This information is usually related to directives, environment data, etc.
9 |
10 | By default, every Zephir extension automatically adds a basic table to the `phpinfo()` output showing the extension version, and any INI options the extension supports.
11 |
12 | You can add more directives by adding the following configuration to the `config.json` file:
13 |
14 | ```json
15 | "info": [
16 | {
17 | "header": ["Directive", "Value"],
18 | "rows": [
19 | ["setting1", "value1"],
20 | ["setting2", "value2"]
21 | ]
22 | },
23 | {
24 | "header": ["Directive", "Value"],
25 | "rows": [
26 | ["setting3", "value3"],
27 | ["setting4", "value4"]
28 | ]
29 | }
30 | ]
31 | ```
32 |
33 | This information will be shown as follows:
34 |
35 | 
36 |
--------------------------------------------------------------------------------
/en/sidebar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Welcome",
4 | "url": "welcome"
5 | },
6 | {
7 | "text": "Why Zephir",
8 | "url": "motivation"
9 | },
10 | {
11 | "text": "Introducing Zephir",
12 | "url": "introduction"
13 | },
14 | {
15 | "text": "Installation",
16 | "url": "installation"
17 | },
18 | {
19 | "text": "Tutorial",
20 | "url": "tutorial"
21 | },
22 | {
23 | "text": "Basic Syntax",
24 | "url": "language"
25 | },
26 | {
27 | "text": "Types",
28 | "url": "types"
29 | },
30 | {
31 | "text": "Operators",
32 | "url": "operators"
33 | },
34 | {
35 | "text": "Operator Precedence",
36 | "url": "operator-precedence"
37 | },
38 | {
39 | "text": "Arrays",
40 | "url": "arrays"
41 | },
42 | {
43 | "text": "Classes and objects",
44 | "url": "oop"
45 | },
46 | {
47 | "text": "Built-in methods",
48 | "url": "builtin-methods"
49 | },
50 | {
51 | "text": "Control structures",
52 | "url": "control-structures"
53 | },
54 | {
55 | "text": "Exceptions",
56 | "url": "exceptions"
57 | },
58 | {
59 | "text": "Calling functions",
60 | "url": "functions"
61 | },
62 | {
63 | "text": "Closures",
64 | "url": "closures"
65 | },
66 | {
67 | "text": "Custom optimizers",
68 | "url": "optimizers"
69 | },
70 | {
71 | "text": "Configuration file",
72 | "url": "config"
73 | },
74 | {
75 | "text": "Command Line",
76 | "url": "command-line"
77 | },
78 | {
79 | "text": "Lifecycle hooks",
80 | "url": "lifecycle"
81 | },
82 | {
83 | "text": "Extension globals",
84 | "url": "globals"
85 | },
86 | {
87 | "text": "phpinfo() sections",
88 | "url": "phpinfo"
89 | },
90 | {
91 | "text": "Static analysis",
92 | "url": "static-analysis"
93 | },
94 | {
95 | "text": "Optimizations",
96 | "url": "optimizations"
97 | },
98 | {
99 | "text": "Compiler warnings",
100 | "url": "warnings"
101 | },
102 | {
103 | "text": "License",
104 | "url": "license"
105 | }
106 | ]
107 |
--------------------------------------------------------------------------------
/en/static-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Static Analysis
8 | Zephir's compiler provides static analysis of the compiled code. The idea behind this feature is to help the developer to find potential problems and avoid unexpected behaviors, well before runtime.
9 |
10 |
11 | ## Conditional Unassigned Variables
12 | Static Analysis of assignments tries to identify if a variable is used before it's assigned:
13 |
14 | ```zephir
15 | class Utils
16 | {
17 | public function someMethod(b)
18 | {
19 | string a; char c;
20 |
21 | if b == 10 {
22 | let a = "hello";
23 | }
24 |
25 | //a could be unitialized here
26 | for c in a {
27 | echo c, PHP_EOL;
28 | }
29 | }
30 | }
31 | ```
32 |
33 | The above example illustrates a common situation. The variable `a` is assigned only when `b` is equal to 10, then it's required to use the value of this variable - but it could be uninitialized. Zephir detects this, automatically initializes the variable to an empty string, and generates a warning alerting the developer:
34 |
35 | ```bash
36 | Warning: Variable 'a' was assigned for the first time in conditional branch,
37 | consider initialize it in its declaration in
38 | /home/scott/test/test/utils.zep on 21 [conditional-initialization]
39 |
40 | for c in a {
41 | ```
42 |
43 | Finding such errors is sometimes tricky, however static analysis helps the programmer to find bugs in advance.
44 |
45 |
46 | ## Dead Code Elimination
47 | Zephir informs the developer about unreachable branches in the code and performs dead code elimination, which means it gets rid of all that code from the generated binary, since it cannot be executed anyway:
48 |
49 | ```zephir
50 | class Utils
51 | {
52 | public function someMethod(b)
53 | {
54 | if false {
55 | // This is never executed
56 | echo "hello";
57 | }
58 | }
59 | }
60 | ```
61 |
--------------------------------------------------------------------------------
/en/warnings.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Compiler Warnings
8 | The compiler raises warnings when it finds situations where the code can be improved, or a potential error can be avoided.
9 |
10 | Warnings can be enabled via command line parameters, or can be added to the `config.json` to enable or disable them more permanently.
11 |
12 | You can enable warnings by passing their name prefixed by `-w`:
13 |
14 | ```bash
15 | zephir -wunused-variable -wnonexistent-function
16 | ```
17 |
18 | Warnings can be disabled by passing their name prefixed by `-W`:
19 |
20 | ```bash
21 | zephir -Wunused-variable -Wnonexistent-function
22 | ```
23 |
24 | The following warnings are supported:
25 |
26 |
27 | ## unused-variable
28 | Raised when a variable is declared but it is not used within a method. This warning is enabled by default.
29 |
30 | ```zephir
31 | public function some()
32 | {
33 | var e; // declared but not used
34 |
35 | return false;
36 | }
37 | ```
38 |
39 |
40 | ## unused-variable-external
41 | Raised when a parameter is declared but it is not used within a method.
42 |
43 | ```zephir
44 | public function sum(a, b, c) // c is not used
45 | {
46 | return a + b;
47 | }
48 | ```
49 |
50 |
51 | ## possible-wrong-parameter-undefined
52 | Raised when a method is called with a wrong type for a parameter:
53 |
54 | ```zephir
55 | public function some()
56 | {
57 | return this->sum("a string", "another"); // wrong parameters passed
58 | }
59 |
60 | public function sum(int a, int b)
61 | {
62 | return a + b;
63 | }
64 | ```
65 |
66 |
67 | ## nonexistent-function
68 | Raised when a function is called that does not exist at compile time:
69 |
70 | ```zephir
71 | public function some()
72 | {
73 | someFunction(); // someFunction does not exist
74 | }
75 | ```
76 |
77 |
78 | ## nonexistent-class
79 | Raised when a class is used that does not exist at compile time:
80 |
81 | ```zephir
82 | public function some()
83 | {
84 | var a;
85 |
86 | let a = new \MyClass(); // MyClass does not exist
87 | }
88 | ```
89 |
90 |
91 | ## non-valid-isset
92 | Raised when the compiler detects that an 'isset' operation is being made on a non-array or -object value:
93 |
94 | ```zephir
95 | public function some()
96 | {
97 | var b = 1.2;
98 |
99 | return isset b[0]; // variable integer 'b' used as array
100 | }
101 | ```
102 |
103 |
104 | ## non-array-update
105 | Raised when the compiler detects that an array update operation is being made on a non-array value:
106 |
107 | ```zephir
108 | public function some()
109 | {
110 | var b = 1.2;
111 | let b[0] = true; // variable 'b' cannot be used as array
112 | }
113 | ```
114 |
115 |
116 | ## non-valid-objectupdate
117 | Raised when the compiler detects that an object update operation is being made on a non-object value:
118 |
119 | ```zephir
120 | public function some()
121 | {
122 | var b = 1.2;
123 | let b->name = true; // variable 'b' cannot be used as object
124 | }
125 | ```
126 |
127 |
128 | ## non-valid-fetch
129 | Raised when the compiler detects that a 'fetch' operation is being made on a non-array or -object value:
130 |
131 | ##### variable integer 'b' used as array
132 |
133 | ```zephir
134 | public function some()
135 | {
136 | var b = 1.2, a;
137 | fetch a, b[0];
138 | }
139 | ```
140 |
141 |
142 | ## invalid-array-index
143 | Raised when the compiler detects that an invalid array index is used:
144 |
145 | ```zephir
146 | public function some(var a)
147 | {
148 | var b = [];
149 | let a[b] = true;
150 | }
151 | ```
152 |
153 |
154 | ## non-array-append
155 | Raised when the compiler detects that an element is being appended to a non-array variable:
156 |
157 | ```zephir
158 | public function some()
159 | {
160 | var b = false;
161 | let b[] = "some value";
162 | }
163 | ```
164 |
--------------------------------------------------------------------------------
/en/welcome.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'en'
4 | version: '0.12'
5 | ---
6 |
7 | # Welcome!
8 | Welcome to Zephir, an open source, high-level/domain specific language designed to ease the creation and maintainability of extensions for PHP, with a focus on type and memory safety.
9 |
10 |
11 | ## Some features
12 | Zephir's main features are:
13 |
14 | | Feature | Description |
15 | |--------------------|-------------------------------------------------------|
16 | | Type system | dynamic/static |
17 | | Memory safety | pointers or direct memory management are not allowed |
18 | | Compilation model | ahead of time |
19 | | Memory model | task-local garbage collection |
20 |
21 |
22 | ## A small taste
23 | The following code registers a class with a method that filters variables, returning their alphabetic characters:
24 |
25 | ```zephir
26 | namespace MyLibrary;
27 |
28 | /**
29 | * Filter
30 | */
31 | class Filter
32 | {
33 | /**
34 | * Filters a string, returning its alpha charactersa
35 | *
36 | * @param string str
37 | */
38 | public function alpha(string str)
39 | {
40 | char ch; string filtered = "";
41 |
42 | for ch in str {
43 | if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
44 | let filtered .= ch;
45 | }
46 | }
47 |
48 | return filtered;
49 | }
50 | }
51 | ```
52 |
53 | The class can be used from PHP as follows:
54 |
55 | ```php
56 | alpha("01he#l.lo?/1"); // prints hello
60 | ```
61 |
62 |
63 | ## External Links
64 | Below we have collected links to external resources that may interest you:
65 |
66 | - [Type system](https://en.wikipedia.org/wiki/Type_system)
67 | - [Memory safety](https://en.wikipedia.org/wiki/Memory_safety)
68 | - [Ahead-of-time compilation](https://en.wikipedia.org/wiki/Ahead-of-time_compilation)
69 | - [Memory management](https://en.wikipedia.org/wiki/Memory_management)
70 |
--------------------------------------------------------------------------------
/es-es/arrays.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Arrays
8 |
9 | La manipulación de arrays o arreglos en Zephir proporciona una manera de utilizar los [arrays de PHP](https://www.php.net/manual/en/language.types.array.php). Un array es una implementación de una [tabla hash](https://en.wikipedia.org/wiki/Hash_table).
10 |
11 |
12 |
13 | ## Declarar Variables de tipo Array
14 |
15 | Variables de array pueden ser declaradas usando las palabras clave 'var' o 'array':
16 |
17 | ```zephir
18 | var a = []; // variable array, el tipo puede ser cambiado
19 | array b = []; // variable array, el tipo no puede ser cambiado durante la ejecución
20 | ```
21 |
22 |
23 |
24 | ## Creación de Arrays
25 |
26 | Un array se crea encerrando sus elementos entre corchetes:
27 |
28 | ##### Crear una arreglo vacío
29 |
30 | ```zephir
31 | let elements = [];
32 | ```
33 |
34 | ##### Crear un arreglo con elementos
35 |
36 | ```zephir
37 | let elements = [1, 3, 4];
38 | ```
39 |
40 | ##### Crear un arreglo con elementos de diferentes tipos
41 |
42 | ```zephir
43 | let elements = ["first", 2, true];
44 | ```
45 |
46 | ##### Un arreglo multidimensional
47 |
48 | ```zephir
49 | let elements = [[0, 1], [4, 5], [2, 3]];
50 | ```
51 |
52 | Al igual que en PHP los hashes o claves están soportadas, también conocidos como arreglos asociativos:
53 |
54 | ##### Creación de un arreglo asociativo con claves de texto
55 |
56 | ```zephir
57 | let elements = ["foo": "bar", "bar": "foo"];
58 | ```
59 |
60 | ##### Creación de un array asociativo con claves numéricas
61 |
62 | ```zephir
63 | let elements = [4: "bar", 8: "foo"];
64 | ```
65 |
66 | ##### Creación de un array asociativo mixto, con claves de texto y numéricas
67 |
68 | ```zephir
69 | let elements = [4: "bar", "foo": 8];
70 | ```
71 |
72 |
73 |
74 | ## Actualización de arrays
75 |
76 | Los arreglos se actualizan en la misma manera que en PHP, utilizando corchetes cuadrados:
77 |
78 | ##### Actualización de un array con una llave de texto
79 |
80 | ```zephir
81 | let elements["foo"] = "bar";
82 | ```
83 |
84 | ##### Actualización de un array con una llave numérica
85 |
86 | ```zephir
87 | let elements[0] = "bar";
88 | ```
89 |
90 | ##### Actualización de un array multidimensional
91 |
92 | ```zephir
93 | let elements[0]["foo"] = "bar";
94 | let elements["foo"][0] = "bar";
95 | ```
96 |
97 |
98 |
99 | ## Agregando elementos
100 |
101 | Los elementos pueden ser añadidos al final del array de la siguiente manera:
102 |
103 | ##### Añadir un nuevo elemento a un array
104 |
105 | ```zephir
106 | let elements[] = "bar";
107 | ```
108 |
109 |
110 |
111 | ## Leyendo elementos desde arrays
112 |
113 | Es posible leer los elementos de la matriz de la siguiente forma:
114 |
115 | ##### Obteniendo un elemento utilizando la clave de texto `foo`
116 |
117 | ```zephir
118 | let foo = elements["foo"];
119 | ```
120 |
121 | ##### Obteniendo un elemento utilizando la clave numérica 0
122 |
123 | ```zephir
124 | let foo = elements[0];
125 | ```
--------------------------------------------------------------------------------
/es-es/closures.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Closures
8 |
9 | You can use closures (a.k.a. anonymous functions) in Zephir; these are PHP compatible and can be returned to the PHP userland:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Functional
15 | {
16 |
17 | public function map(array! data)
18 | {
19 | return function(number) {
20 | return number * number;
21 | };
22 | }
23 | }
24 | ```
25 |
26 | It also can be executed directly within Zephir, and passed as a parameter to other functions/methods:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Functional
32 | {
33 |
34 | public function map(array! data)
35 | {
36 | return data->map(function(number) {
37 | return number * number;
38 | });
39 | }
40 | }
41 | ```
42 |
43 | A short syntax is also available to define closures:
44 |
45 | ```zephir
46 | namespace MyLibrary;
47 |
48 | class Functional
49 | {
50 |
51 | public function map(array! data)
52 | {
53 | return data->map(number => number * number);
54 | }
55 | }
56 | ```
--------------------------------------------------------------------------------
/es-es/command-line.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # The Zephir Command Line
8 |
9 | Once Zephir is installed, you'll use the `zephir` command to manage the Zephir compiler for your projects. This chapter, and the ones following, are about the command itself, how to use it, and how to understand the things it outputs.
10 |
11 | As of Zephir 0.11.7, the compiler makes use of `stderr` for displaying error messages. This means you can handle error outputs separately from normal ones, like so:
12 |
13 | ```bash
14 | zephir generate 2> errors.log 1> /dev/null
15 | ```
16 |
17 |
18 |
19 | ## `zephir api`
20 |
21 | Generates an HTML API based on the classes exposed in the extension
22 |
23 | - `--backend=BACKEND`: Backend used to generate HTML API (default: `ZendEngine3`)
24 | - `--path=PATH` (or `-p PATH`): The API theme to be used
25 | - `--output=OUTPUT` (or `-o OUTPUT`): Output directory to generate theme
26 | - `--options=OPTIONS`: Theme options
27 | - `--url=URL`: The base URL to be used when generating links
28 |
29 |
30 |
31 | ## `zephir build`
32 |
33 | This is a meta command that just calls the [`generate`](#zephir-generate), [`compile`](#zephir-compile), and [`install`](#zephir-install) commands. Check those commands for more information on supported options and behaviors for each.
34 |
35 |
36 |
37 | ## `zephir clean`
38 |
39 | Cleans any object files created by the extension
40 |
41 |
42 |
43 | ## `zephir compile`
44 |
45 | Compile a Zephir extension
46 |
47 | - `--backend=BACKEND`: Backend used to build extension (default: `ZendEngine3`)
48 | - `--dev`: Build the extension in development mode
49 | - `--no-dev`: Build the extension in production mode
50 |
51 | Using `--dev` option will force building and installing the extension in development mode (debug symbols and no optimizations). An extension compiled with debugging symbols means you can run a program or library through a debugger and the debugger's output will be user friendlier. These debugging symbols also enlarge the program or library significantly.
52 |
53 | NOTE: Zephir development mode will be enabled silently if your PHP binary was compiled in a debug configuration.
54 |
55 | In some cases, we would like to get production ready extension even if the PHP binary was compiled in a debug configuration. Use `--no-dev` option to achieve this behavior.
56 |
57 | Additionally, any of the options available [under `extra` in the configuration file](/{{ page.version }}/{{ page.language }}/config#extra) can also be passed as options, here, such as `--export-classes` and `--indent=tabs`.
58 |
59 |
60 |
61 | ## `zephir fullclean`
62 |
63 | Cleans any object files created by the extension (including files generated by phpize)
64 |
65 |
66 |
67 | ## `zephir generate`
68 |
69 | Generates C code from the Zephir code
70 |
71 | - `--backend=BACKEND`: Backend used to build extension (default: `ZendEngine3`)
72 |
73 |
74 |
75 | ## `zephir help`
76 |
77 | Displays help for a command
78 |
79 |
80 |
81 | ## `zephir init`
82 |
83 | Initializes a Zephir extension `zephir init `
84 |
85 | - `namespace`: The extension namespace
86 | - `--backend=BACKEND`: Backend used to create extension (default: `ZendEngine3`)
87 |
88 |
89 |
90 | ## `zephir install`
91 |
92 | Installs the extension in the extension directory (may require root password)
93 |
94 | - `--dev`: Install the extension in development mode
95 | - `--no-dev`: Install the extension in production mode
96 |
97 |
98 |
99 | ## `zephir list`
100 |
101 | Lists commands
102 |
103 |
104 |
105 | ## `zephir stubs`
106 |
107 | Generates stubs that can be used in a PHP IDE
108 |
109 | - `--backend=BACKEND`: Backend used to generate stubs (default: `ZendEngine3`)
110 |
--------------------------------------------------------------------------------
/es-es/exceptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Exceptions
8 |
9 | Zephir implements exceptions at a very low level, providing similar behavior and functionality to PHP.
10 |
11 | When an exception is thrown, a `catch` block can be used to capture the exception and allow the developer to provide proper handling:
12 |
13 | Exceptions can be thrown inside the `try` block. Handling happens in the `catch` block, exactly as in PHP:
14 |
15 | ```zephir
16 | var e;
17 | try {
18 |
19 | throw new \Exception("This is an exception");
20 |
21 | } catch \Exception, e {
22 |
23 | echo e->getMessage();
24 | }
25 | ```
26 |
27 | Zephir also provides a "silent" `try` block, that simply ignores any exceptions produced within that block:
28 |
29 | ```zephir
30 | try {
31 | throw new \Exception("This is an exception");
32 | }
33 | ```
34 |
35 | If you don't need an exception variable when 'catch'ing, then you can safely not provide it:
36 |
37 | ```zephir
38 | try {
39 |
40 | throw new \Exception("This is an exception");
41 |
42 | } catch \Exception {
43 |
44 | echo "An exception occur!";
45 | }
46 | ```
47 |
48 | A single `catch` block can be used to catch multiple types of exception:
49 |
50 | ```zephir
51 | var e;
52 | try {
53 |
54 | throw new \Exception("This is an exception");
55 |
56 | } catch \RuntimeException|\Exception, e {
57 |
58 | echo e->getMessage();
59 | }
60 | ```
61 |
62 | Zephir allows you to throw literals or static typed variables as if they were the message of the exception:
63 |
64 | ```zephir
65 | // throw new \Exception("Test");
66 | throw "Test";
67 |
68 | // throw new \Exception((string) 't');
69 | throw 't';
70 |
71 | // throw new \Exception((string) 123);
72 | throw 123;
73 |
74 | // throw new \Exception((string) 123.123);
75 | throw 123.123;
76 | ```
77 |
78 | Zephir's exceptions provide the same methods to know where the exception happened that PHP's exceptions do. That is, `Exception::getFile()` and `Exception::getLine()` return the location in the Zephir code where the exception was thrown:
79 |
80 | ```bash
81 | Exception: The static method 'someMethod' does not exist on model 'Robots'
82 | File=phalcon/mvc/model.zep Line=4042
83 | #0 /home/scott/test.php(64): Phalcon\Mvc\Model::__callStatic('someMethod', Array)
84 | #1 /home/scott/test.php(64): Robots::someMethod()
85 | #2 {main}
86 | ```
--------------------------------------------------------------------------------
/es-es/functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Calling Functions
8 |
9 | PHP has a rich library of functions that you can use within your extensions. To call a PHP function you simply use it as normal within your Zephir code:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Encoder
15 | {
16 | public function encode(var text)
17 | {
18 | if strlen(text) != 0 {
19 | return base64_encode(text);
20 | }
21 | return false;
22 | }
23 | }
24 | ```
25 |
26 | You can also call functions that are expected to exist in the PHP userland, but are not necessarily built in to PHP itself:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Encoder
32 | {
33 |
34 | public function encode(var text)
35 | {
36 | if strlen(text) != 0 {
37 | if function_exists("my_custom_encoder") {
38 | return my_custom_encoder(text);
39 | } else {
40 | return base64_encode(text);
41 | }
42 | }
43 | return false;
44 | }
45 | }
46 | ```
47 |
48 | Note that all PHP functions only receive and return dynamic variables. If you pass a static typed variable as a parameter, a temporary dynamic variable will automatically be used as a bridge in order to call the function:
49 |
50 | ```zephir
51 | namespace MyLibrary;
52 |
53 | class Encoder
54 | {
55 | public function encode(string text)
56 | {
57 | if strlen(text) != 0 {
58 | // an implicit dynamic variable is created to
59 | // pass the static typed 'text' as parameter
60 | return base64_encode(text);
61 | }
62 | return false;
63 | }
64 | }
65 | ```
66 |
67 | Similarly, functions return dynamic values, which cannot be directly assigned to static variables without the appropriate explicit cast:
68 |
69 | ```zephir
70 | namespace MyLibrary;
71 |
72 | class Encoder
73 | {
74 | public function encode(string text)
75 | {
76 | string encoded = "";
77 |
78 | if strlen(text) != 0 {
79 | let encoded = (string) base64_encode(text);
80 | return "(" . encoded . ")";
81 | }
82 | return false;
83 | }
84 | }
85 | ```
86 |
87 | Zephir also provides a way for you to call functions dynamically, such as:
88 |
89 | ```zephir
90 | namespace MyLibrary;
91 |
92 | class Encoder
93 | {
94 | public function encode(var callback, string text)
95 | {
96 | return {callback}(text);
97 | }
98 | }
99 | ```
--------------------------------------------------------------------------------
/es-es/globals.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Extension Globals
8 |
9 | PHP extensions provide a way to define globals within an extension. Reading/writing globals should be faster than any other global mechanisms (like static members). You can use extension globals to set up configuration options that change the behavior of your library.
10 |
11 | In Zephir, extension globals are restricted to simple scalar types like `int`/`bool`/`double`/`char`, etc. Complex types such as string/array/object/resource are not allowed here.
12 |
13 | You can enable extension globals by adding the following structure to your `config.json`:
14 |
15 | ```json
16 | {
17 | "globals": {
18 | "allow_some_feature": {
19 | "type": "bool",
20 | "default": true,
21 | "module": true
22 | },
23 | "number_times": {
24 | "type": "int",
25 | "default": 10
26 | },
27 | "some_component.my_setting_1": {
28 | "type": "bool",
29 | "default": true
30 | },
31 | "some_component.my_setting_2": {
32 | "type": "int",
33 | "default": 100
34 | }
35 | }
36 | }
37 | ```
38 |
39 | Each global has the following structure:
40 |
41 | ```json
42 | "": {
43 | "type": "",
44 | "default":
45 | }
46 | ```
47 |
48 | Compound (namespaced) globals have the following structure:
49 |
50 | ```json
51 | ".": {
52 | "type": "",
53 | "default":
54 | }
55 | ```
56 |
57 | The optional `module` key, if present, places that global's initialization process into the module-wide `GINIT` lifecycle event, which just means it will only be set up once per PHP process, rather than being reinitialized for every request, which is the default:
58 |
59 | ```json
60 | {
61 | "globals": {
62 | "allow_some_feature": {
63 | "type": "bool",
64 | "default": true,
65 | "module": true
66 | },
67 | "number_times": {
68 | "type": "int",
69 | "default": 10
70 | }
71 | }
72 | }
73 | ```
74 |
75 | In the example above, `allow_some_feature` is set up only once at startup; `number_times` is set up at the start of each request.
76 |
77 | Inside any method, you can read/write extension globals using the built-in functions `globals_get`/`globals_set`:
78 |
79 | ```zephir
80 | globals_set("allow_some_feature", true);
81 | let someFeature = globals_get("allow_some_feature");
82 | ```
83 |
84 | If you want to change these globals from PHP, a good option is include a method aimed at this:
85 |
86 | ```zephir
87 | namespace Test;
88 |
89 | class MyOptions
90 | {
91 |
92 | public static function setOptions(array options)
93 | {
94 | boolean someOption, anotherOption;
95 |
96 | if fetch someOption, options["some_option"] {
97 | globals_set("some_option", someOption);
98 | }
99 |
100 | if fetch anotherOption, options["another_option"] {
101 | globals_set("another_option", anotherOption);
102 | }
103 | }
104 | }
105 | ```
106 |
107 | Extension globals cannot be dynamically accessed, since the C code generated by the `globals_get`/`globals_set` optimizers must be resolved at compilation time:
108 |
109 | ```zephir
110 | let myOption = "someOption";
111 |
112 | // will throw a compiler exception
113 | let someOption = globals_get(myOption);
114 | ```
--------------------------------------------------------------------------------
/es-es/license.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Licencia
8 |
9 | MIT License
10 |
11 | Copyright (c) 2013-present Zephir Team
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/es-es/operator-precedence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Operator Precedence
8 | **Operator precedence** determines how operators are parsed. Operators with higher precedence become the operands of operators with lower precedence. For example, in the expression `1 + 5 * 3`, the answer is 16 and not 18 because the multiplication (`*`) operator has a higher precedence than the addition (`+`) operator. Parentheses may be used to force precedence, if necessary. For instance: `(1 + 5) * 3` evaluates to 18.
9 |
10 |
11 |
12 | ## Associativity
13 | When operators have equal precedence their **associativity** determines how the operators are grouped. For example `-` is _left-associative_, so `1 - 2 - 3` is grouped as `(1 - 2) - 3` and evaluates to `-4`. `=` on the other hand is _right-associative_, so `let a = b = c` is grouped as `let a = (b = c)`.
14 |
15 | Operators of equal precedence that are _non-associative_ cannot be used next to one another. For example:
16 | ```zep
17 | new new Foo();
18 | ```
19 | is illegal in Zephir, because the `new` is non-associative. At the moment, `new` is the only non-associative operator in Zephir.
20 |
21 | Use of parentheses, even when not strictly necessary, can often increase readability of the code, by making grouping explicit, rather than relying on the implicit operator precedence and associativity.
22 |
23 |
24 |
25 | ## Precedence Table
26 | The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides grouping.
27 |
28 | | Precedence | Operadores | Operator type | Associativity |
29 | | ---------- | -------------------------------- | ----------------------------------- | --------------- |
30 | | 1 | `->` | Member Access | right-to-left |
31 | | 2 | `~` | Bitwise NOT | right-to-left |
32 | | 3 | `!` | Logical NOT | right-to-left |
33 | | 4 | `new` | new | non-associative |
34 | | 5 | `clone` | clone | right-to-left |
35 | | 6 | `typeof` | Type-of | right-to-left |
36 | | 7 | `..`, `...` | Inclusive/exclusive range | left-to-right |
37 | | 8 | `isset`, `fetch`, `empty` | Exclusive range | right-to-left |
38 | | 9 | `*`, `/`, `%` | Multiplication, Division, Remainder | left-to-right |
39 | | 10 | `+`, `-`, `.` | Addition, Subtraction, Concat | left-to-right |
40 | | 11 | `<<`, `>>` | Bitwise shift left/right | left-to-right |
41 | | 12 | `<`, `<=`, `=>`, `>` | Comparison | left-to-right |
42 | | 13 | `==`, `!==`, `===`, `!==` | Comparison | left-to-right |
43 | | 14 | `&` | Bitwise AND, references | left-to-right |
44 | | 15 | `^` | Bitwise XOR | left-to-right |
45 | | 16 | `|` | Bitwise OR | left-to-right |
46 | | 17 | `instanceof` | Instance-of | left-to-right |
47 | | 18 | `&&` | Logical AND | left-to-right |
48 | | 19 | `||` | Logical OR | left-to-right |
49 | | 20 | `likely`, `unlikely` | Branch prediction | right-to-left |
50 | | 21 | `?` | Logical | right-to-left |
51 | | 21 | `=>` | Closure Arrow | right-to-left |
52 |
--------------------------------------------------------------------------------
/es-es/phpinfo.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Phpinfo() Secciones
8 |
9 | Like most extensions, Zephir extensions are able to show information in the [phpinfo()](https://php.net/manual/en/function.phpinfo.php) output. Esta información está usualmente relacionada con directivas, datos de entorno, etc.
10 |
11 | Por defecto, cada extensión de Zephir automáticamente agrega una tabla básica de datos a la salida de `phpinfo()` mostrando la versión de la extensión, y cualquier opción INI que soporte la extensión.
12 |
13 | Usted puede agregar más directivas agregando la siguiente configuración al archivo `config.json`:
14 |
15 | ```json
16 | "info": [
17 | {
18 | "header": ["Directive", "Value"],
19 | "rows": [
20 | ["setting1", "value1"],
21 | ["setting2", "value2"]
22 | ]
23 | },
24 | {
25 | "header": ["Directive", "Value"],
26 | "rows": [
27 | ["setting3", "value3"],
28 | ["setting4", "value4"]
29 | ]
30 | }
31 | ]
32 | ```
33 |
34 | Esta información se mostrará de la siguiente manera:
35 |
36 | 
--------------------------------------------------------------------------------
/es-es/sidebar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Welcome",
4 | "url": "welcome"
5 | },
6 | {
7 | "text": "Why Zephir",
8 | "url": "motivation"
9 | },
10 | {
11 | "text": "Introducción a Zephir",
12 | "url": "introduction"
13 | },
14 | {
15 | "text": "Instalación",
16 | "url": "installation"
17 | },
18 | {
19 | "text": "Tutorial",
20 | "url": "tutorial"
21 | },
22 | {
23 | "text": "Sintaxis básica",
24 | "url": "language"
25 | },
26 | {
27 | "text": "Tipos",
28 | "url": "types"
29 | },
30 | {
31 | "text": "Operadores",
32 | "url": "operators"
33 | },
34 | {
35 | "text": "Operator Precedence",
36 | "url": "operator-precedence"
37 | },
38 | {
39 | "text": "Arrays",
40 | "url": "arrays"
41 | },
42 | {
43 | "text": "Classes and objects",
44 | "url": "oop"
45 | },
46 | {
47 | "text": "Built-in methods",
48 | "url": "builtin-methods"
49 | },
50 | {
51 | "text": "Control structures",
52 | "url": "control-structures"
53 | },
54 | {
55 | "text": "Exceptions",
56 | "url": "exceptions"
57 | },
58 | {
59 | "text": "Calling functions",
60 | "url": "functions"
61 | },
62 | {
63 | "text": "Closures",
64 | "url": "closures"
65 | },
66 | {
67 | "text": "Custom optimizers",
68 | "url": "optimizers"
69 | },
70 | {
71 | "text": "Configuration file",
72 | "url": "config"
73 | },
74 | {
75 | "text": "Command Line",
76 | "url": "command-line"
77 | },
78 | {
79 | "text": "Lifecycle hooks",
80 | "url": "lifecycle"
81 | },
82 | {
83 | "text": "Extension globals",
84 | "url": "globals"
85 | },
86 | {
87 | "text": "phpinfo() sections",
88 | "url": "phpinfo"
89 | },
90 | {
91 | "text": "Static analysis",
92 | "url": "static-analysis"
93 | },
94 | {
95 | "text": "Optimizations",
96 | "url": "optimizations"
97 | },
98 | {
99 | "text": "Compiler warnings",
100 | "url": "warnings"
101 | },
102 | {
103 | "text": "Licencia",
104 | "url": "license"
105 | }
106 | ]
107 |
--------------------------------------------------------------------------------
/es-es/static-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # Static Analysis
8 |
9 | Zephir's compiler provides static analysis of the compiled code. The idea behind this feature is to help the developer to find potential problems and avoid unexpected behaviors, well before runtime.
10 |
11 |
12 |
13 | ## Conditional Unassigned Variables
14 |
15 | Static Analysis of assignments tries to identify if a variable is used before it's assigned:
16 |
17 | ```zephir
18 | class Utils
19 | {
20 | public function someMethod(b)
21 | {
22 | string a; char c;
23 |
24 | if b == 10 {
25 | let a = "hello";
26 | }
27 |
28 | //a could be unitialized here
29 | for c in a {
30 | echo c, PHP_EOL;
31 | }
32 | }
33 | }
34 | ```
35 |
36 | The above example illustrates a common situation. The variable `a` is assigned only when `b` is equal to 10, then it's required to use the value of this variable - but it could be uninitialized. Zephir detects this, automatically initializes the variable to an empty string, and generates a warning alerting the developer:
37 |
38 | ```bash
39 | Warning: Variable 'a' was assigned for the first time in conditional branch,
40 | consider initialize it in its declaration in
41 | /home/scott/test/test/utils.zep on 21 [conditional-initialization]
42 |
43 | for c in a {
44 | ```
45 |
46 | Finding such errors is sometimes tricky, however static analysis helps the programmer to find bugs in advance.
47 |
48 |
49 |
50 | ## Dead Code Elimination
51 |
52 | Zephir informs the developer about unreachable branches in the code and performs dead code elimination, which means it gets rid of all that code from the generated binary, since it cannot be executed anyway:
53 |
54 | ```zephir
55 | class Utils
56 | {
57 | public function someMethod(b)
58 | {
59 | if false {
60 | // This is never executed
61 | echo "hello";
62 | }
63 | }
64 | }
65 | ```
--------------------------------------------------------------------------------
/es-es/welcome.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'es-es'
4 | version: '0.12'
5 | ---
6 |
7 | # ¡Bienvenido!
8 |
9 | Bienvenido a Zephir, un lenguaje de código abierto de alto nivel/dominio específico, diseñado para facilitar la creación y mantenimiento de extensiones para PHP con un enfoque de tipo y cuidado de memoria.
10 |
11 |
12 |
13 | ## Algunas características
14 |
15 | Las principales características de Zephir son:
16 |
17 | | Características | Descripción |
18 | | --------------------- | ------------------------------------------------------- |
19 | | Tipo de sistema | dinámica/estática |
20 | | Ahorro de memoria | punteros o gestión de memoria directa no está permitido |
21 | | Modelo de compilación | adelantado |
22 | | Modelo de memoria | recolección local de basura |
23 |
24 |
25 |
26 | ## Una pequeña prueba
27 |
28 | El siguiente código registra una clase con un método que filtra variables, regresando sus caracteres alfabéticos:
29 |
30 | ```zephir
31 | namespace MyLibrary;
32 |
33 | /**
34 | * Filtro
35 | */
36 | class Filter
37 | {
38 | /**
39 | * Filtra una cadena de texto, retornando solo caracteres alfabéticos
40 | *
41 | * @param string str
42 | */
43 | public function alpha(string str)
44 | {
45 | char ch; string filtered = "";
46 |
47 | for ch in str {
48 | if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
49 | let filtered .= ch;
50 | }
51 | }
52 |
53 | return filtered;
54 | }
55 | }
56 | ```
57 |
58 | La clase puede ser utiliza desde PHP de la siguiente manera:
59 |
60 | ```php
61 | alpha("01ho#.la?/1"); // imprime hola
65 | ```
66 |
67 |
68 |
69 | ## Enlaces externos
70 |
71 | A continuación hemos recopilado enlaces a recursos externos que te pueden interesar:
72 |
73 | - [Tipo de sistema](https://en.wikipedia.org/wiki/Type_system)
74 | - [Ahorro de memoria](https://en.wikipedia.org/wiki/Memory_safety)
75 | - [Compilación Ahead-of-time](https://en.wikipedia.org/wiki/Ahead-of-time_compilation)
76 | - [Gestión de la memoria](https://en.wikipedia.org/wiki/Memory_management)
--------------------------------------------------------------------------------
/ru-ru/arrays.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Массивы
8 |
9 | Работа с массивами в Zephir происходит таким же образом как и с [массивами в PHP](https://www.php.net/manual/en/language.types.array.php). An array is an implementation of a [hash table](https://en.wikipedia.org/wiki/Hash_table).
10 |
11 |
12 |
13 | ## Объявление массивов
14 |
15 | Массивы могут быть объявлены с помощью ключевых слов 'var' или 'array':
16 |
17 | ```zephir
18 | var a = []; // массив, с возможностью переопределения типа
19 | array b = []; // массив, без возможности переопределения типа
20 | ```
21 |
22 |
23 |
24 | ## Создание массивов
25 |
26 | Массив создается путём заключения его элементов в квадратные скобки:
27 |
28 | ##### Создание пустого массива
29 |
30 | ```zephir
31 | let elements = [];
32 | ```
33 |
34 | ##### Создание массива с элементами
35 |
36 | ```zephir
37 | let elements = [1, 3, 4];
38 | ```
39 |
40 | ##### Создание массива с элементами разных типов
41 |
42 | ```zephir
43 | let elements = ["first", 2, true];
44 | ```
45 |
46 | ##### Создание многомерного массива
47 |
48 | ```zephir
49 | let elements = [[0, 1], [4, 5], [2, 3]];
50 | ```
51 |
52 | Как и в PHP, поддерживаются простые (списки) и ассоциативные массивы:
53 |
54 | ##### Создание массива с строковыми ключами
55 |
56 | ```zephir
57 | let elements = ["foo": "bar", "bar": "foo"];
58 | ```
59 |
60 | ##### Создание массива с числовыми ключами
61 |
62 | ```zephir
63 | let elements = [4: "bar", 8: "foo"];
64 | ```
65 |
66 | ##### Создание массива со смешанными ключами (строковые и числовые)
67 |
68 | ```zephir
69 | let elements = [4: "bar", "foo": 8];
70 | ```
71 |
72 |
73 |
74 | ## Обновление массивов
75 |
76 | Массивы обновляются так же, как в PHP, используя квадратные скобки:
77 |
78 | ##### Обновление массива с строковым ключём
79 |
80 | ```zephir
81 | let elements["foo"] = "bar";
82 | ```
83 |
84 | ##### Обновление массива с числовым ключем
85 |
86 | ```zephir
87 | let elements[0] = "bar";
88 | ```
89 |
90 | ##### Обновление многомерного массива
91 |
92 | ```zephir
93 | let elements[0]["foo"] = "bar";
94 | let elements["foo"][0] = "bar";
95 | ```
96 |
97 |
98 |
99 | ## Добавление элементов
100 |
101 | Элементы могут быть добавлены в конце массива следующим образом:
102 |
103 | ##### Добавление элемента в массив
104 |
105 | ```zephir
106 | let elements[] = "bar";
107 | ```
108 |
109 |
110 |
111 | ## Чтение элементов из массивов
112 |
113 | Можно прочитать элементы массива следующим образом:
114 |
115 | ##### Получение элемента используя строковый ключ `foo`
116 |
117 | ```zephir
118 | let foo = elements["foo"];
119 | ```
120 |
121 | ##### Получение элемента используя числовой ключ 0
122 |
123 | ```zephir
124 | let foo = elements[0];
125 | ```
--------------------------------------------------------------------------------
/ru-ru/closures.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Замыкания
8 |
9 | В Zephir вы можете использовать анонимные функции (также известные как замыкания); Они совместимы с PHP и могут передаваться в область видимости PHP кода:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Functional
15 | {
16 |
17 | public function map(array! data)
18 | {
19 | return function(number) {
20 | return number * number;
21 | };
22 | }
23 | }
24 | ```
25 |
26 | Они также могут быть выполнены непосредственно в Zephir, и переданы в качестве параметра другим функциям/методам:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Functional
32 | {
33 |
34 | public function map(array! data)
35 | {
36 | return data->map(function(number) {
37 | return number * number;
38 | });
39 | }
40 | }
41 | ```
42 |
43 | Для определения замыканий доступен также короткий синтаксис:
44 |
45 | ```zephir
46 | namespace MyLibrary;
47 |
48 | class Functional
49 | {
50 |
51 | public function map(array! data)
52 | {
53 | return data->map(number => number * number);
54 | }
55 | }
56 | ```
--------------------------------------------------------------------------------
/ru-ru/exceptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Исключения
8 |
9 | Zephir реализует исключения на очень низком уровне, обеспечивая подобное PHP поведение и функциональность.
10 |
11 | Когда генерируется исключение, блок `catch` может быть использован для перехвата исключения и предоставления разработчику возможности обеспечить надлежащую обработку:
12 |
13 | Исключения могут быть выброшены внутри блока `try`. Обработка происходит в блоке `catch` точно так же, как в PHP:
14 |
15 | ```zephir
16 | var e;
17 | try {
18 |
19 | throw new \Exception("Это - исключение");
20 |
21 | } catch \Exception, e {
22 |
23 | echo e->getMessage();
24 | }
25 | ```
26 |
27 | Zephir также предоставляет "тихий" блок `try`, который просто игнорирует любые исключения, генерируемые внутри этого блока:
28 |
29 | ```zephir
30 | try {
31 | throw new \Exception("Это исключение");
32 | }
33 | ```
34 |
35 | Если вам не нужна переменная исключения при его перехвате, вы можете не указать её:
36 |
37 | ```zephir
38 | try {
39 |
40 | throw new \Exception("Это исключение");
41 |
42 | } catch \Exception {
43 |
44 | echo "An exception occur!";
45 | }
46 | ```
47 |
48 | Один `catch` блок может использоваться для перехвата нескольких типов исключений:
49 |
50 | ```zephir
51 | var e;
52 | try {
53 |
54 | throw new \Exception("Это исключение");
55 |
56 | } catch \RuntimeException|\Exception, e {
57 |
58 | echo e->getMessage();
59 | }
60 | ```
61 |
62 | Zephir позволяет выбрасывать любые литеры или статически типизированные переменные, как если бы они были сообщением исключения:
63 |
64 | ```zephir
65 | // throw new \Exception("Тест");
66 | throw "Тест";
67 |
68 | // throw new \Exception((string) 't');
69 | throw 't';
70 |
71 | // throw new \Exception((string) 123);
72 | throw 123;
73 |
74 | // throw new \Exception((string) 123.123);
75 | throw 123.123;
76 | ```
77 |
78 | Исключения Zephir предоставляют те же методы, что и исключения PHP, чтобы узнать, где произошло исключение. Таким образом, `Exception::getFile()` и ` Exception::getLine()` возвращают имя файла и номер строки соотвественно, где в Zephir коде было выброшено исключение:
79 |
80 | ```bash
81 | Exception: The static method 'someMethod' does not exist on model 'Robots'
82 | File=phalcon/mvc/model.zep Line=4042
83 | #0 /home/scott/test.php(64): Phalcon\Mvc\Model::__callStatic('someMethod', Array)
84 | #1 /home/scott/test.php(64): Robots::someMethod()
85 | #2 {main}
86 | ```
--------------------------------------------------------------------------------
/ru-ru/functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Вызов функций
8 |
9 | PHP имеет богатую библиотеку функций, которые вы можете использовать в своих расширениях. Чтобы вызвать функцию PHP, вы просто используете её как обычно в своем коде Zephir:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Encoder
15 | {
16 | public function encode(var text)
17 | {
18 | if strlen(text) != 0 {
19 | return base64_encode(text);
20 | }
21 | return false;
22 | }
23 | }
24 | ```
25 |
26 | Вы также можете вызывать функции, которые, как ожидается, существуют в пользовательском окружении PHP, но не встроены в PHP:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Encoder
32 | {
33 |
34 | public function encode(var text)
35 | {
36 | if strlen(text) != 0 {
37 | if function_exists("my_custom_encoder") {
38 | return my_custom_encoder(text);
39 | } else {
40 | return base64_encode(text);
41 | }
42 | }
43 | return false;
44 | }
45 | }
46 | ```
47 |
48 | Обратите внимание, что все PHP-функции только получают и возвращают динамические переменные. Если вы передаете статически типизированную переменную в качестве параметра, то в качестве моста для вызова функции будет создана временная динамическая переменная:
49 |
50 | ```zephir
51 | namespace MyLibrary;
52 |
53 | class Encoder
54 | {
55 | public function encode(string text)
56 | {
57 | if strlen(text) != 0 {
58 | // an implicit dynamic variable is created to
59 | // pass the static typed 'text' as parameter
60 | return base64_encode(text);
61 | }
62 | return false;
63 | }
64 | }
65 | ```
66 |
67 | Аналогично, функции возвращают динамические значения, которые не могут быть напрямую назначены статическим переменным без соответствующего приведения:
68 |
69 | ```zephir
70 | namespace MyLibrary;
71 |
72 | class Encoder
73 | {
74 | public function encode(string text)
75 | {
76 | string encoded = "";
77 |
78 | if strlen(text) != 0 {
79 | let encoded = (string) base64_encode(text);
80 | return "(" . encoded . ")";
81 | }
82 | return false;
83 | }
84 | }
85 | ```
86 |
87 | Zephir также предоставляет способ для динамического вызова функций, например:
88 |
89 | ```zephir
90 | namespace MyLibrary;
91 |
92 | class Encoder
93 | {
94 | public function encode(var callback, string text)
95 | {
96 | return {callback}(text);
97 | }
98 | }
99 | ```
--------------------------------------------------------------------------------
/ru-ru/globals.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Глобальные параметры расширения
8 |
9 | PHP расширения предоставляют способ определения глобальных переменных, которые будут доступны из любого места расширения. Операции чтения и записи таких переменных обычно выполняются быстрее, чем любые другие глобальные механизмы (например, доступ к статическим членам). Глобальные переменные расширения можно использовать для настройки параметров конфигурации, которые изменяют поведение вашей библиотеки.
10 |
11 | В Zephir глобальные переменные ограничены простыми скалярными типами такими как `int`, `bool`, `double`, `char` и т.д. Здесь не допускаются комплексные типы, такие как строки, массивы, объекты и ресурсы.
12 |
13 | Вы можете ввести глобальные переменные в расширение, добавив следующую структуру в `config.json`:
14 |
15 | ```json
16 | {
17 | "globals": {
18 | "allow_some_feature": {
19 | "type": "bool",
20 | "default": true,
21 | "module": true
22 | },
23 | "number_times": {
24 | "type": "int",
25 | "default": 10
26 | },
27 | "some_component.my_setting_1": {
28 | "type": "bool",
29 | "default": true
30 | },
31 | "some_component.my_setting_2": {
32 | "type": "int",
33 | "default": 100
34 | }
35 | }
36 | }
37 | ```
38 |
39 | Каждая глобальная переменная имеет следующую структуру:
40 |
41 | ```json
42 | "": {
43 | "type": "",
44 | "default":
45 | }
46 | ```
47 |
48 | Составные (именованные) глобальные переменные имеют следующую структуру:
49 |
50 | ```json
51 | ".": {
52 | "type": "",
53 | "default":
54 | }
55 | ```
56 |
57 | Необязательный ключ `module`, если он присутствует, помещает процесс инициализации параметра в глобальное событие расширения `GINIT`. Это означает, что параметр будет инициализирован указанным значением только один раз для каждого процесса PHP, а не будет повторно инициализирован для каждого запроса, что является значением по умолчанию:
58 |
59 | ```json
60 | {
61 | "globals": {
62 | "allow_some_feature": {
63 | "type": "bool",
64 | "default": true,
65 | "module": true
66 | },
67 | "number_times": {
68 | "type": "int",
69 | "default": 10
70 | }
71 | }
72 | }
73 | ```
74 |
75 | В примере выше, `allow_some_feature` настраивается только один раз при запуске; `number_times` устанавливается в начале каждого запроса.
76 |
77 | Доступ к глобальным переменным может быть осуществлён из любого метода расширения при помощи встроенных функций `globals_get` и `globals_set`:
78 |
79 | ```zephir
80 | globals_set("allow_some_feature", true);
81 | let someFeature = globals_get("allow_some_feature");
82 | ```
83 |
84 | Если вы хотите получать доступ к этим глобальным переменным из PHP, то неплохим вариантом является создание метода, направленного на это:
85 |
86 | ```zephir
87 | namespace Test;
88 |
89 | class MyOptions
90 | {
91 |
92 | public static function setOptions(array options)
93 | {
94 | boolean someOption, anotherOption;
95 |
96 | if fetch someOption, options["some_option"] {
97 | globals_set("some_option", someOption);
98 | }
99 |
100 | if fetch anotherOption, options["another_option"] {
101 | globals_set("another_option", anotherOption);
102 | }
103 | }
104 | }
105 | ```
106 |
107 | Доступ к глобальным переменным расширения не может быть осуществлен с помощью динамически вычисляемого кода. Это связанно с тем, что C-код, сгенерированный оптимизаторами функций `globals_get` и `globals_set`, должен быть вычислен во время компиляции:
108 |
109 | ```zephir
110 | let myOption = "someOption";
111 |
112 | // Выбросит ошибку компиляции
113 | let someOption = globals_get(myOption);
114 | ```
--------------------------------------------------------------------------------
/ru-ru/license.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Лицензионное соглашение
8 |
9 | Лицензия MIT
10 |
11 | Copyright (c) 2013 - по настоящее время: Команда Zephir
12 |
13 | Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, слияние, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, а также лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий:
14 |
15 | Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения.
16 |
17 | ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА УЩЕРБ ИЛИ ПО ИНЫМ ТРЕБОВАНИЯМ, В ТОМ ЧИСЛЕ, ПРИ ДЕЙСТВИИ КОНТРАКТА, ДЕЛИКТЕ ИЛИ ИНОЙ СИТУАЦИИ, ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
--------------------------------------------------------------------------------
/ru-ru/operator-precedence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Operator Precedence
8 | **Operator precedence** determines how operators are parsed. Operators with higher precedence become the operands of operators with lower precedence. For example, in the expression `1 + 5 * 3`, the answer is 16 and not 18 because the multiplication (`*`) operator has a higher precedence than the addition (`+`) operator. Parentheses may be used to force precedence, if necessary. For instance: `(1 + 5) * 3` evaluates to 18.
9 |
10 |
11 |
12 | ## Associativity
13 | When operators have equal precedence their **associativity** determines how the operators are grouped. For example `-` is _left-associative_, so `1 - 2 - 3` is grouped as `(1 - 2) - 3` and evaluates to `-4`. `=` on the other hand is _right-associative_, so `let a = b = c` is grouped as `let a = (b = c)`.
14 |
15 | Operators of equal precedence that are _non-associative_ cannot be used next to one another. For example:
16 | ```zep
17 | new new Foo();
18 | ```
19 | is illegal in Zephir, because the `new` is non-associative. At the moment, `new` is the only non-associative operator in Zephir.
20 |
21 | Use of parentheses, even when not strictly necessary, can often increase readability of the code, by making grouping explicit, rather than relying on the implicit operator precedence and associativity.
22 |
23 |
24 |
25 | ## Precedence Table
26 | The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides grouping.
27 |
28 | | Precedence | Операторы | Operator type | Associativity |
29 | | ---------- | -------------------------------- | ----------------------------------- | --------------- |
30 | | 1 | `->` | Member Access | right-to-left |
31 | | 2 | `~` | Bitwise NOT | right-to-left |
32 | | 3 | `!` | Logical NOT | right-to-left |
33 | | 4 | `new` | new | non-associative |
34 | | 5 | `clone` | clone | right-to-left |
35 | | 6 | `typeof` | Type-of | right-to-left |
36 | | 7 | `..`, `...` | Inclusive/exclusive range | left-to-right |
37 | | 8 | `isset`, `fetch`, `empty` | Exclusive range | right-to-left |
38 | | 9 | `*`, `/`, `%` | Multiplication, Division, Remainder | left-to-right |
39 | | 10 | `+`, `-`, `.` | Addition, Subtraction, Concat | left-to-right |
40 | | 11 | `<<`, `>>` | Bitwise shift left/right | left-to-right |
41 | | 12 | `<`, `<=`, `=>`, `>` | Comparison | left-to-right |
42 | | 13 | `==`, `!==`, `===`, `!==` | Comparison | left-to-right |
43 | | 14 | `&` | Bitwise AND, references | left-to-right |
44 | | 15 | `^` | Bitwise XOR | left-to-right |
45 | | 16 | `|` | Bitwise OR | left-to-right |
46 | | 17 | `instanceof` | Instance-of | left-to-right |
47 | | 18 | `&&` | Logical AND | left-to-right |
48 | | 19 | `||` | Logical OR | left-to-right |
49 | | 20 | `likely`, `unlikely` | Branch prediction | right-to-left |
50 | | 21 | `?` | Logical | right-to-left |
51 | | 21 | `=>` | Closure Arrow | right-to-left |
52 |
--------------------------------------------------------------------------------
/ru-ru/phpinfo.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Секции phpinfo()
8 |
9 | Как и большинство расширений, расширения написанные на Zephir могут отображать информацию при выводе [phpinfo()](https://php.net/manual/en/function.phpinfo.php). Обычно эта информация относится к директивам, данным окружения и т.п.
10 |
11 | По умолчанию, каждое Zephir расширение добавляет базовую таблицу в вывод `phpinfo()` отображающую версию расширения.
12 |
13 | Вы можете добавить больше директив, добавив следующую конфигурацию в файл `config.json`:
14 |
15 | ```json
16 | "info": [
17 | {
18 | "header": ["Directive", "Value"],
19 | "rows": [
20 | ["setting1", "value1"],
21 | ["setting2", "value2"]
22 | ]
23 | },
24 | {
25 | "header": ["Directive", "Value"],
26 | "rows": [
27 | ["setting3", "value3"],
28 | ["setting4", "value4"]
29 | ]
30 | }
31 | ]
32 | ```
33 |
34 | Эта информация будет отображена следующим образом:
35 |
36 | 
--------------------------------------------------------------------------------
/ru-ru/sidebar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Добро пожаловать",
4 | "url": "welcome"
5 | },
6 | {
7 | "text": "Почему Zephir",
8 | "url": "motivation"
9 | },
10 | {
11 | "text": "Введение в Zephir",
12 | "url": "introduction"
13 | },
14 | {
15 | "text": "Установка",
16 | "url": "installation"
17 | },
18 | {
19 | "text": "Урок",
20 | "url": "tutorial"
21 | },
22 | {
23 | "text": "Базовый синтаксис",
24 | "url": "language"
25 | },
26 | {
27 | "text": "Типы",
28 | "url": "types"
29 | },
30 | {
31 | "text": "Операторы",
32 | "url": "operators"
33 | },
34 | {
35 | "text": "Operator Precedence",
36 | "url": "operator-precedence"
37 | },
38 | {
39 | "text": "Массивы",
40 | "url": "arrays"
41 | },
42 | {
43 | "text": "Классы и объекты",
44 | "url": "oop"
45 | },
46 | {
47 | "text": "Встроенные методы",
48 | "url": "builtin-methods"
49 | },
50 | {
51 | "text": "Управляющие структуры",
52 | "url": "control-structures"
53 | },
54 | {
55 | "text": "Исключения",
56 | "url": "exceptions"
57 | },
58 | {
59 | "text": "Вызов функции",
60 | "url": "functions"
61 | },
62 | {
63 | "text": "Замыкания",
64 | "url": "closures"
65 | },
66 | {
67 | "text": "Настраиваемые оптимизаторы",
68 | "url": "optimizers"
69 | },
70 | {
71 | "text": "Конфигурационный файл",
72 | "url": "config"
73 | },
74 | {
75 | "text": "Командная строка",
76 | "url": "command-line"
77 | },
78 | {
79 | "text": "Хуки жизненного цикла",
80 | "url": "lifecycle"
81 | },
82 | {
83 | "text": "Глобальные параметры расширения",
84 | "url": "globals"
85 | },
86 | {
87 | "text": "Секции phpinfo()",
88 | "url": "phpinfo"
89 | },
90 | {
91 | "text": "Статический анализ",
92 | "url": "static-analysis"
93 | },
94 | {
95 | "text": "Оптимизации",
96 | "url": "optimizations"
97 | },
98 | {
99 | "text": "Предупреждения компилятора",
100 | "url": "warnings"
101 | },
102 | {
103 | "text": "Лицензионное соглашение",
104 | "url": "license"
105 | }
106 | ]
107 |
--------------------------------------------------------------------------------
/ru-ru/static-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Статический анализ
8 |
9 | Компилятор Zephir предоставляет возможность статического анализа компилируемого кода. Идея этой функции заключается в том, чтобы помочь разработчику найти потенциальные проблемы и избежать неожиданного поведения задолго до времени исполнения.
10 |
11 |
12 |
13 | ## Условные неинициализированные переменные
14 |
15 | При присвоении значения переменно статический анализатор пытается определить, используется ли переменная до ее инициализации:
16 |
17 | ```zephir
18 | class Utils
19 | {
20 | public function someMethod(b)
21 | {
22 | string a; char c;
23 |
24 | if b == 10 {
25 | let a = "привет";
26 | }
27 |
28 | // Есть вероятность, что переменная "a" не определена
29 | for c in a {
30 | echo c, PHP_EOL;
31 | }
32 | }
33 | }
34 | ```
35 |
36 | Приведенный выше пример иллюстрирует общую ситуацию. Переменной `a` будет присвоено значение только в том случае, если переменная `b` равна 10, но как видно из этого примера, значение проверяемой переменной не определено в явном виде. Компилятор Zephir определяет это, автоматически инициализирует переменную в пустую строку и генерирует предупреждение разработчику:
37 |
38 | ```bash
39 | Warning: Variable 'a' was assigned for the first time in conditional branch,
40 | consider initialize it in its declaration in
41 | /home/scott/test/test/utils.zep on 21 [conditional-initialization]
42 |
43 | for c in a {
44 | ```
45 |
46 | Обнаружить такие ошибки иногда сложно, однако статический анализ помогает программисту обнаружить ошибки заранее.
47 |
48 |
49 |
50 | ## Удаление мёртвого кода
51 |
52 | Zephir информирует разработчика о недоступных ветвях в коде и выполняет удаление мертвого кода, это означает, что он избавляется от всего этого кода из сгенерированного двоичного файла, поскольку он никогда не сможет быть запущен:
53 |
54 | ```zephir
55 | class Utils
56 | {
57 | public function someMethod(b)
58 | {
59 | if false {
60 | // Этот код никогда не выполнится
61 | echo "hello";
62 | }
63 | }
64 | }
65 | ```
--------------------------------------------------------------------------------
/ru-ru/welcome.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'ru-ru'
4 | version: '0.12'
5 | ---
6 |
7 | # Добро пожаловать!
8 |
9 | Встречайте Zephir, открытый, высокоуровневый, специализированный язык разработанный для быстрого и удобного создания расширений для PHP с упором на типизацию и безопасное управление памятью.
10 |
11 |
12 |
13 | ## Некоторые особенности
14 |
15 | Основные особенности Zephir:
16 |
17 | | Особенность | Описание |
18 | | ----------------------------- | --------------------------------------------- |
19 | | Система типов | динамическая/статическая |
20 | | Безопасность доступа к памяти | указатели и ручное выделение памяти запрещены |
21 | | Модель компиляции | перед исполнением (AOT-компиляция) |
22 | | Управление памятью | свой сборщик мусора |
23 |
24 |
25 |
26 | ## Попробуйте
27 |
28 | Этот код регистрирует класс с методом, который оставляет в строке только буквы:
29 |
30 | ```zephir
31 | namespace MyLibrary;
32 |
33 | /**
34 | * Filter
35 | */
36 | class Filter
37 | {
38 | /**
39 | * Filters a string, returning its alpha charactersa
40 | *
41 | * @param string str
42 | */
43 | public function alpha(string str)
44 | {
45 | char ch; string filtered = "";
46 |
47 | for ch in str {
48 | if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
49 | let filtered .= ch;
50 | }
51 | }
52 |
53 | return filtered;
54 | }
55 | }
56 | ```
57 |
58 | А теперь используем этот класс в PHP:
59 |
60 | ```php
61 | alpha("01he#l.lo?/1"); // выведет hello
65 | ```
66 |
67 |
68 |
69 | ## Внешние ссылки
70 |
71 | Ниже мы собрали ссылки на внешние ресурсы, которые могу вас заинтересовать:
72 |
73 | - [Система типов](https://en.wikipedia.org/wiki/Type_system)
74 | - [Безопасность доступа к памяти](https://en.wikipedia.org/wiki/Memory_safety)
75 | - [AOT-компиляция](https://en.wikipedia.org/wiki/Ahead-of-time_compilation)
76 | - [Управление памятью](https://en.wikipedia.org/wiki/Memory_management)
--------------------------------------------------------------------------------
/tr-tr/arrays.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Arrays
8 |
9 | Array manipulation in Zephir provides a way to use PHP [array](https://www.php.net/manual/en/language.types.array.php). An array is an implementation of a [hash table](https://en.wikipedia.org/wiki/Hash_table).
10 |
11 |
12 |
13 | ## Declaring Array Variables
14 |
15 | Array variables can be declared using the keywords 'var' or 'array':
16 |
17 | ```zephir
18 | var a = []; // array variable, its type can be changed
19 | array b = []; // array variable, its type cannot be changed across execution
20 | ```
21 |
22 |
23 |
24 | ## Creating Arrays
25 |
26 | An array is created by enclosing its elements in square brackets:
27 |
28 | ##### Creating an empty array
29 |
30 | ```zephir
31 | let elements = [];
32 | ```
33 |
34 | ##### Creating an array with elements
35 |
36 | ```zephir
37 | let elements = [1, 3, 4];
38 | ```
39 |
40 | ##### Creating an array with elements of different types
41 |
42 | ```zephir
43 | let elements = ["first", 2, true];
44 | ```
45 |
46 | ##### A multidimensional array
47 |
48 | ```zephir
49 | let elements = [[0, 1], [4, 5], [2, 3]];
50 | ```
51 |
52 | As PHP, hashes or dictionaries are supported:
53 |
54 | ##### Creating a hash with string keys
55 |
56 | ```zephir
57 | let elements = ["foo": "bar", "bar": "foo"];
58 | ```
59 |
60 | ##### Creating a hash with numeric keys
61 |
62 | ```zephir
63 | let elements = [4: "bar", 8: "foo"];
64 | ```
65 |
66 | ##### Creating a hash with mixed string and numeric keys
67 |
68 | ```zephir
69 | let elements = [4: "bar", "foo": 8];
70 | ```
71 |
72 |
73 |
74 | ## Updating arrays
75 |
76 | Arrays are updated in the same way as PHP, using square brackets:
77 |
78 | ##### Updating an array with a string key
79 |
80 | ```zephir
81 | let elements["foo"] = "bar";
82 | ```
83 |
84 | ##### Updating an array with a numeric key
85 |
86 | ```zephir
87 | let elements[0] = "bar";
88 | ```
89 |
90 | ##### Updating multi-dimensional array
91 |
92 | ```zephir
93 | let elements[0]["foo"] = "bar";
94 | let elements["foo"][0] = "bar";
95 | ```
96 |
97 |
98 |
99 | ## Appending elements
100 |
101 | Elements can be appended at the end of the array as follows:
102 |
103 | ##### Append an element to the array
104 |
105 | ```zephir
106 | let elements[] = "bar";
107 | ```
108 |
109 |
110 |
111 | ## Reading elements from arrays
112 |
113 | It is possible to read array elements as follows:
114 |
115 | ##### Getting an element using the string key `foo`
116 |
117 | ```zephir
118 | let foo = elements["foo"];
119 | ```
120 |
121 | ##### Getting an element using the numeric key 0
122 |
123 | ```zephir
124 | let foo = elements[0];
125 | ```
--------------------------------------------------------------------------------
/tr-tr/closures.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Closures
8 |
9 | You can use closures (a.k.a. anonymous functions) in Zephir; these are PHP compatible and can be returned to the PHP userland:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Functional
15 | {
16 |
17 | public function map(array! data)
18 | {
19 | return function(number) {
20 | return number * number;
21 | };
22 | }
23 | }
24 | ```
25 |
26 | It also can be executed directly within Zephir, and passed as a parameter to other functions/methods:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Functional
32 | {
33 |
34 | public function map(array! data)
35 | {
36 | return data->map(function(number) {
37 | return number * number;
38 | });
39 | }
40 | }
41 | ```
42 |
43 | A short syntax is also available to define closures:
44 |
45 | ```zephir
46 | namespace MyLibrary;
47 |
48 | class Functional
49 | {
50 |
51 | public function map(array! data)
52 | {
53 | return data->map(number => number * number);
54 | }
55 | }
56 | ```
--------------------------------------------------------------------------------
/tr-tr/command-line.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # The Zephir Command Line
8 |
9 | Once Zephir is installed, you'll use the `zephir` command to manage the Zephir compiler for your projects. This chapter, and the ones following, are about the command itself, how to use it, and how to understand the things it outputs.
10 |
11 | As of Zephir 0.11.7, the compiler makes use of `stderr` for displaying error messages. This means you can handle error outputs separately from normal ones, like so:
12 |
13 | ```bash
14 | zephir generate 2> errors.log 1> /dev/null
15 | ```
16 |
17 |
18 |
19 | ## `zephir api`
20 |
21 | Generates an HTML API based on the classes exposed in the extension
22 |
23 | - `--backend=BACKEND`: Backend used to generate HTML API (default: `ZendEngine3`)
24 | - `--path=PATH` (or `-p PATH`): The API theme to be used
25 | - `--output=OUTPUT` (or `-o OUTPUT`): Output directory to generate theme
26 | - `--options=OPTIONS`: Theme options
27 | - `--url=URL`: The base URL to be used when generating links
28 |
29 |
30 |
31 | ## `zephir build`
32 |
33 | This is a meta command that just calls the [`generate`](#zephir-generate), [`compile`](#zephir-compile), and [`install`](#zephir-install) commands. Check those commands for more information on supported options and behaviors for each.
34 |
35 |
36 |
37 | ## `zephir clean`
38 |
39 | Cleans any object files created by the extension
40 |
41 |
42 |
43 | ## `zephir compile`
44 |
45 | Compile a Zephir extension
46 |
47 | - `--backend=BACKEND`: Backend used to build extension (default: `ZendEngine3`)
48 | - `--dev`: Build the extension in development mode
49 | - `--no-dev`: Build the extension in production mode
50 |
51 | Using `--dev` option will force building and installing the extension in development mode (debug symbols and no optimizations). An extension compiled with debugging symbols means you can run a program or library through a debugger and the debugger's output will be user friendlier. These debugging symbols also enlarge the program or library significantly.
52 |
53 | NOTE: Zephir development mode will be enabled silently if your PHP binary was compiled in a debug configuration.
54 |
55 | In some cases, we would like to get production ready extension even if the PHP binary was compiled in a debug configuration. Use `--no-dev` option to achieve this behavior.
56 |
57 | Additionally, any of the options available [under `extra` in the configuration file](/{{ page.version }}/{{ page.language }}/config#extra) can also be passed as options, here, such as `--export-classes` and `--indent=tabs`.
58 |
59 |
60 |
61 | ## `zephir fullclean`
62 |
63 | Cleans any object files created by the extension (including files generated by phpize)
64 |
65 |
66 |
67 | ## `zephir generate`
68 |
69 | Generates C code from the Zephir code
70 |
71 | - `--backend=BACKEND`: Backend used to build extension (default: `ZendEngine3`)
72 |
73 |
74 |
75 | ## `zephir help`
76 |
77 | Displays help for a command
78 |
79 |
80 |
81 | ## `zephir init`
82 |
83 | Initializes a Zephir extension `zephir init `
84 |
85 | - `namespace`: The extension namespace
86 | - `--backend=BACKEND`: Backend used to create extension (default: `ZendEngine3`)
87 |
88 |
89 |
90 | ## `zephir install`
91 |
92 | Installs the extension in the extension directory (may require root password)
93 |
94 | - `--dev`: Install the extension in development mode
95 | - `--no-dev`: Install the extension in production mode
96 |
97 |
98 |
99 | ## `zephir list`
100 |
101 | Lists commands
102 |
103 |
104 |
105 | ## `zephir stubs`
106 |
107 | Generates stubs that can be used in a PHP IDE
108 |
109 | - `--backend=BACKEND`: Backend used to generate stubs (default: `ZendEngine3`)
110 |
--------------------------------------------------------------------------------
/tr-tr/exceptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Exceptions
8 |
9 | Zephir implements exceptions at a very low level, providing similar behavior and functionality to PHP.
10 |
11 | When an exception is thrown, a `catch` block can be used to capture the exception and allow the developer to provide proper handling:
12 |
13 | Exceptions can be thrown inside the `try` block. Handling happens in the `catch` block, exactly as in PHP:
14 |
15 | ```zephir
16 | var e;
17 | try {
18 |
19 | throw new \Exception("This is an exception");
20 |
21 | } catch \Exception, e {
22 |
23 | echo e->getMessage();
24 | }
25 | ```
26 |
27 | Zephir also provides a "silent" `try` block, that simply ignores any exceptions produced within that block:
28 |
29 | ```zephir
30 | try {
31 | throw new \Exception("This is an exception");
32 | }
33 | ```
34 |
35 | If you don't need an exception variable when 'catch'ing, then you can safely not provide it:
36 |
37 | ```zephir
38 | try {
39 |
40 | throw new \Exception("This is an exception");
41 |
42 | } catch \Exception {
43 |
44 | echo "An exception occur!";
45 | }
46 | ```
47 |
48 | A single `catch` block can be used to catch multiple types of exception:
49 |
50 | ```zephir
51 | var e;
52 | try {
53 |
54 | throw new \Exception("This is an exception");
55 |
56 | } catch \RuntimeException|\Exception, e {
57 |
58 | echo e->getMessage();
59 | }
60 | ```
61 |
62 | Zephir allows you to throw literals or static typed variables as if they were the message of the exception:
63 |
64 | ```zephir
65 | // throw new \Exception("Test");
66 | throw "Test";
67 |
68 | // throw new \Exception((string) 't');
69 | throw 't';
70 |
71 | // throw new \Exception((string) 123);
72 | throw 123;
73 |
74 | // throw new \Exception((string) 123.123);
75 | throw 123.123;
76 | ```
77 |
78 | Zephir's exceptions provide the same methods to know where the exception happened that PHP's exceptions do. That is, `Exception::getFile()` and `Exception::getLine()` return the location in the Zephir code where the exception was thrown:
79 |
80 | ```bash
81 | Exception: The static method 'someMethod' does not exist on model 'Robots'
82 | File=phalcon/mvc/model.zep Line=4042
83 | #0 /home/scott/test.php(64): Phalcon\Mvc\Model::__callStatic('someMethod', Array)
84 | #1 /home/scott/test.php(64): Robots::someMethod()
85 | #2 {main}
86 | ```
--------------------------------------------------------------------------------
/tr-tr/functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Calling Functions
8 |
9 | PHP has a rich library of functions that you can use within your extensions. To call a PHP function you simply use it as normal within your Zephir code:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Encoder
15 | {
16 | public function encode(var text)
17 | {
18 | if strlen(text) != 0 {
19 | return base64_encode(text);
20 | }
21 | return false;
22 | }
23 | }
24 | ```
25 |
26 | You can also call functions that are expected to exist in the PHP userland, but are not necessarily built in to PHP itself:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Encoder
32 | {
33 |
34 | public function encode(var text)
35 | {
36 | if strlen(text) != 0 {
37 | if function_exists("my_custom_encoder") {
38 | return my_custom_encoder(text);
39 | } else {
40 | return base64_encode(text);
41 | }
42 | }
43 | return false;
44 | }
45 | }
46 | ```
47 |
48 | Note that all PHP functions only receive and return dynamic variables. If you pass a static typed variable as a parameter, a temporary dynamic variable will automatically be used as a bridge in order to call the function:
49 |
50 | ```zephir
51 | namespace MyLibrary;
52 |
53 | class Encoder
54 | {
55 | public function encode(string text)
56 | {
57 | if strlen(text) != 0 {
58 | // an implicit dynamic variable is created to
59 | // pass the static typed 'text' as parameter
60 | return base64_encode(text);
61 | }
62 | return false;
63 | }
64 | }
65 | ```
66 |
67 | Similarly, functions return dynamic values, which cannot be directly assigned to static variables without the appropriate explicit cast:
68 |
69 | ```zephir
70 | namespace MyLibrary;
71 |
72 | class Encoder
73 | {
74 | public function encode(string text)
75 | {
76 | string encoded = "";
77 |
78 | if strlen(text) != 0 {
79 | let encoded = (string) base64_encode(text);
80 | return "(" . encoded . ")";
81 | }
82 | return false;
83 | }
84 | }
85 | ```
86 |
87 | Zephir also provides a way for you to call functions dynamically, such as:
88 |
89 | ```zephir
90 | namespace MyLibrary;
91 |
92 | class Encoder
93 | {
94 | public function encode(var callback, string text)
95 | {
96 | return {callback}(text);
97 | }
98 | }
99 | ```
--------------------------------------------------------------------------------
/tr-tr/globals.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Extension Globals
8 |
9 | PHP extensions provide a way to define globals within an extension. Reading/writing globals should be faster than any other global mechanisms (like static members). You can use extension globals to set up configuration options that change the behavior of your library.
10 |
11 | In Zephir, extension globals are restricted to simple scalar types like `int`/`bool`/`double`/`char`, etc. Complex types such as string/array/object/resource are not allowed here.
12 |
13 | You can enable extension globals by adding the following structure to your `config.json`:
14 |
15 | ```json
16 | {
17 | "globals": {
18 | "allow_some_feature": {
19 | "type": "bool",
20 | "default": true,
21 | "module": true
22 | },
23 | "number_times": {
24 | "type": "int",
25 | "default": 10
26 | },
27 | "some_component.my_setting_1": {
28 | "type": "bool",
29 | "default": true
30 | },
31 | "some_component.my_setting_2": {
32 | "type": "int",
33 | "default": 100
34 | }
35 | }
36 | }
37 | ```
38 |
39 | Each global has the following structure:
40 |
41 | ```json
42 | "": {
43 | "type": "",
44 | "default":
45 | }
46 | ```
47 |
48 | Compound (namespaced) globals have the following structure:
49 |
50 | ```json
51 | ".": {
52 | "type": "",
53 | "default":
54 | }
55 | ```
56 |
57 | The optional `module` key, if present, places that global's initialization process into the module-wide `GINIT` lifecycle event, which just means it will only be set up once per PHP process, rather than being reinitialized for every request, which is the default:
58 |
59 | ```json
60 | {
61 | "globals": {
62 | "allow_some_feature": {
63 | "type": "bool",
64 | "default": true,
65 | "module": true
66 | },
67 | "number_times": {
68 | "type": "int",
69 | "default": 10
70 | }
71 | }
72 | }
73 | ```
74 |
75 | In the example above, `allow_some_feature` is set up only once at startup; `number_times` is set up at the start of each request.
76 |
77 | Inside any method, you can read/write extension globals using the built-in functions `globals_get`/`globals_set`:
78 |
79 | ```zephir
80 | globals_set("allow_some_feature", true);
81 | let someFeature = globals_get("allow_some_feature");
82 | ```
83 |
84 | If you want to change these globals from PHP, a good option is include a method aimed at this:
85 |
86 | ```zephir
87 | namespace Test;
88 |
89 | class MyOptions
90 | {
91 |
92 | public static function setOptions(array options)
93 | {
94 | boolean someOption, anotherOption;
95 |
96 | if fetch someOption, options["some_option"] {
97 | globals_set("some_option", someOption);
98 | }
99 |
100 | if fetch anotherOption, options["another_option"] {
101 | globals_set("another_option", anotherOption);
102 | }
103 | }
104 | }
105 | ```
106 |
107 | Extension globals cannot be dynamically accessed, since the C code generated by the `globals_get`/`globals_set` optimizers must be resolved at compilation time:
108 |
109 | ```zephir
110 | let myOption = "someOption";
111 |
112 | // will throw a compiler exception
113 | let someOption = globals_get(myOption);
114 | ```
--------------------------------------------------------------------------------
/tr-tr/license.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # License
8 |
9 | MIT License
10 |
11 | Copyright (c) 2013-present Zephir Team
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/tr-tr/operator-precedence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Operator Precedence
8 | **Operator precedence** determines how operators are parsed. Operators with higher precedence become the operands of operators with lower precedence. For example, in the expression `1 + 5 * 3`, the answer is 16 and not 18 because the multiplication (`*`) operator has a higher precedence than the addition (`+`) operator. Parentheses may be used to force precedence, if necessary. For instance: `(1 + 5) * 3` evaluates to 18.
9 |
10 |
11 |
12 | ## Associativity
13 | When operators have equal precedence their **associativity** determines how the operators are grouped. For example `-` is _left-associative_, so `1 - 2 - 3` is grouped as `(1 - 2) - 3` and evaluates to `-4`. `=` on the other hand is _right-associative_, so `let a = b = c` is grouped as `let a = (b = c)`.
14 |
15 | Operators of equal precedence that are _non-associative_ cannot be used next to one another. For example:
16 | ```zep
17 | new new Foo();
18 | ```
19 | is illegal in Zephir, because the `new` is non-associative. At the moment, `new` is the only non-associative operator in Zephir.
20 |
21 | Use of parentheses, even when not strictly necessary, can often increase readability of the code, by making grouping explicit, rather than relying on the implicit operator precedence and associativity.
22 |
23 |
24 |
25 | ## Precedence Table
26 | The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides grouping.
27 |
28 | | Precedence | Operators | Operator type | Associativity |
29 | | ---------- | -------------------------------- | ----------------------------------- | --------------- |
30 | | 1 | `->` | Member Access | right-to-left |
31 | | 2 | `~` | Bitwise NOT | right-to-left |
32 | | 3 | `!` | Logical NOT | right-to-left |
33 | | 4 | `new` | new | non-associative |
34 | | 5 | `clone` | clone | right-to-left |
35 | | 6 | `typeof` | Type-of | right-to-left |
36 | | 7 | `..`, `...` | Inclusive/exclusive range | left-to-right |
37 | | 8 | `isset`, `fetch`, `empty` | Exclusive range | right-to-left |
38 | | 9 | `*`, `/`, `%` | Multiplication, Division, Remainder | left-to-right |
39 | | 10 | `+`, `-`, `.` | Addition, Subtraction, Concat | left-to-right |
40 | | 11 | `<<`, `>>` | Bitwise shift left/right | left-to-right |
41 | | 12 | `<`, `<=`, `=>`, `>` | Comparison | left-to-right |
42 | | 13 | `==`, `!==`, `===`, `!==` | Comparison | left-to-right |
43 | | 14 | `&` | Bitwise AND, references | left-to-right |
44 | | 15 | `^` | Bitwise XOR | left-to-right |
45 | | 16 | `|` | Bitwise OR | left-to-right |
46 | | 17 | `instanceof` | Instance-of | left-to-right |
47 | | 18 | `&&` | Logical AND | left-to-right |
48 | | 19 | `||` | Logical OR | left-to-right |
49 | | 20 | `likely`, `unlikely` | Branch prediction | right-to-left |
50 | | 21 | `?` | Logical | right-to-left |
51 | | 21 | `=>` | Closure Arrow | right-to-left |
52 |
--------------------------------------------------------------------------------
/tr-tr/phpinfo.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Phpinfo() sections
8 |
9 | Like most extensions, Zephir extensions are able to show information in the [phpinfo()](https://php.net/manual/en/function.phpinfo.php) output. This information is usually related to directives, environment data, etc.
10 |
11 | By default, every Zephir extension automatically adds a basic table to the `phpinfo()` output showing the extension version, and any INI options the extension supports.
12 |
13 | You can add more directives by adding the following configuration to the `config.json` file:
14 |
15 | ```json
16 | "info": [
17 | {
18 | "header": ["Directive", "Value"],
19 | "rows": [
20 | ["setting1", "value1"],
21 | ["setting2", "value2"]
22 | ]
23 | },
24 | {
25 | "header": ["Directive", "Value"],
26 | "rows": [
27 | ["setting3", "value3"],
28 | ["setting4", "value4"]
29 | ]
30 | }
31 | ]
32 | ```
33 |
34 | This information will be shown as follows:
35 |
36 | 
--------------------------------------------------------------------------------
/tr-tr/sidebar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Welcome",
4 | "url": "welcome"
5 | },
6 | {
7 | "text": "Why Zephir",
8 | "url": "motivation"
9 | },
10 | {
11 | "text": "Introducing Zephir",
12 | "url": "introduction"
13 | },
14 | {
15 | "text": "Installation",
16 | "url": "installation"
17 | },
18 | {
19 | "text": "Tutorial",
20 | "url": "tutorial"
21 | },
22 | {
23 | "text": "Basic Syntax",
24 | "url": "language"
25 | },
26 | {
27 | "text": "Types",
28 | "url": "types"
29 | },
30 | {
31 | "text": "Operators",
32 | "url": "operators"
33 | },
34 | {
35 | "text": "Operator Precedence",
36 | "url": "operator-precedence"
37 | },
38 | {
39 | "text": "Arrays",
40 | "url": "arrays"
41 | },
42 | {
43 | "text": "Classes and objects",
44 | "url": "oop"
45 | },
46 | {
47 | "text": "Built-in methods",
48 | "url": "builtin-methods"
49 | },
50 | {
51 | "text": "Control structures",
52 | "url": "control-structures"
53 | },
54 | {
55 | "text": "Exceptions",
56 | "url": "exceptions"
57 | },
58 | {
59 | "text": "Calling functions",
60 | "url": "functions"
61 | },
62 | {
63 | "text": "Closures",
64 | "url": "closures"
65 | },
66 | {
67 | "text": "Custom optimizers",
68 | "url": "optimizers"
69 | },
70 | {
71 | "text": "Configuration file",
72 | "url": "config"
73 | },
74 | {
75 | "text": "Command Line",
76 | "url": "command-line"
77 | },
78 | {
79 | "text": "Lifecycle hooks",
80 | "url": "lifecycle"
81 | },
82 | {
83 | "text": "Extension globals",
84 | "url": "globals"
85 | },
86 | {
87 | "text": "phpinfo() sections",
88 | "url": "phpinfo"
89 | },
90 | {
91 | "text": "Static analysis",
92 | "url": "static-analysis"
93 | },
94 | {
95 | "text": "Optimizations",
96 | "url": "optimizations"
97 | },
98 | {
99 | "text": "Compiler warnings",
100 | "url": "warnings"
101 | },
102 | {
103 | "text": "License",
104 | "url": "license"
105 | }
106 | ]
107 |
--------------------------------------------------------------------------------
/tr-tr/static-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Static Analysis
8 |
9 | Zephir's compiler provides static analysis of the compiled code. The idea behind this feature is to help the developer to find potential problems and avoid unexpected behaviors, well before runtime.
10 |
11 |
12 |
13 | ## Conditional Unassigned Variables
14 |
15 | Static Analysis of assignments tries to identify if a variable is used before it's assigned:
16 |
17 | ```zephir
18 | class Utils
19 | {
20 | public function someMethod(b)
21 | {
22 | string a; char c;
23 |
24 | if b == 10 {
25 | let a = "hello";
26 | }
27 |
28 | //a could be unitialized here
29 | for c in a {
30 | echo c, PHP_EOL;
31 | }
32 | }
33 | }
34 | ```
35 |
36 | The above example illustrates a common situation. The variable `a` is assigned only when `b` is equal to 10, then it's required to use the value of this variable - but it could be uninitialized. Zephir detects this, automatically initializes the variable to an empty string, and generates a warning alerting the developer:
37 |
38 | ```bash
39 | Warning: Variable 'a' was assigned for the first time in conditional branch,
40 | consider initialize it in its declaration in
41 | /home/scott/test/test/utils.zep on 21 [conditional-initialization]
42 |
43 | for c in a {
44 | ```
45 |
46 | Finding such errors is sometimes tricky, however static analysis helps the programmer to find bugs in advance.
47 |
48 |
49 |
50 | ## Dead Code Elimination
51 |
52 | Zephir informs the developer about unreachable branches in the code and performs dead code elimination, which means it gets rid of all that code from the generated binary, since it cannot be executed anyway:
53 |
54 | ```zephir
55 | class Utils
56 | {
57 | public function someMethod(b)
58 | {
59 | if false {
60 | // This is never executed
61 | echo "hello";
62 | }
63 | }
64 | }
65 | ```
--------------------------------------------------------------------------------
/tr-tr/welcome.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'tr-tr'
4 | version: '0.12'
5 | ---
6 |
7 | # Welcome!
8 |
9 | Welcome to Zephir, an open source, high-level/domain specific language designed to ease the creation and maintainability of extensions for PHP, with a focus on type and memory safety.
10 |
11 |
12 |
13 | ## Some features
14 |
15 | Zephir's main features are:
16 |
17 | | Feature | Description |
18 | | ----------------- | ---------------------------------------------------- |
19 | | Type system | dynamic/static |
20 | | Memory safety | pointers or direct memory management are not allowed |
21 | | Compilation model | ahead of time |
22 | | Memory model | task-local garbage collection |
23 |
24 |
25 |
26 | ## A small taste
27 |
28 | The following code registers a class with a method that filters variables, returning their alphabetic characters:
29 |
30 | ```zephir
31 | namespace MyLibrary;
32 |
33 | /**
34 | * Filter
35 | */
36 | class Filter
37 | {
38 | /**
39 | * Filters a string, returning its alpha charactersa
40 | *
41 | * @param string str
42 | */
43 | public function alpha(string str)
44 | {
45 | char ch; string filtered = "";
46 |
47 | for ch in str {
48 | if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
49 | let filtered .= ch;
50 | }
51 | }
52 |
53 | return filtered;
54 | }
55 | }
56 | ```
57 |
58 | The class can be used from PHP as follows:
59 |
60 | ```php
61 | alpha("01he#l.lo?/1"); // prints hello
65 | ```
66 |
67 |
68 |
69 | ## External Links
70 |
71 | Below we have collected links to external resources that may interest you:
72 |
73 | - [Type system](https://en.wikipedia.org/wiki/Type_system)
74 | - [Memory safety](https://en.wikipedia.org/wiki/Memory_safety)
75 | - [Ahead-of-time compilation](https://en.wikipedia.org/wiki/Ahead-of-time_compilation)
76 | - [Memory management](https://en.wikipedia.org/wiki/Memory_management)
--------------------------------------------------------------------------------
/uk-ua/arrays.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Масиви
8 |
9 | Робота з масивами в Zephir здійснюється таким самим чином, [як і в PHP](https://www.php.net/manual/en/language.types.array.php). An array is an implementation of a [hash table](https://en.wikipedia.org/wiki/Hash_table).
10 |
11 |
12 |
13 | ## Оголошення масивів
14 |
15 | Масив можна оголосити за допомогою двох ключслів `var` та `array`:
16 |
17 | ```zephir
18 | var a = []; // масив, з можливістю зміни типу
19 | array b = []; // масив, без можливості зміни типу
20 | ```
21 |
22 |
23 |
24 | ## Створення масивів
25 |
26 | Масив створюється шляхом укладення його елементів в квадратні дужки:
27 |
28 | ##### Створення порожнього масиву
29 |
30 | ```zephir
31 | let elements = [];
32 | ```
33 |
34 | ##### Створення масиву з елементами
35 |
36 | ```zephir
37 | let elements = [1, 3, 4];
38 | ```
39 |
40 | ##### Створення масиву з елементами різних типів
41 |
42 | ```zephir
43 | let elements = ["first", 2, true];
44 | ```
45 |
46 | ##### Створення багатовимірного масиву
47 |
48 | ```zephir
49 | let elements = [[0, 1], [4, 5], [2, 3]];
50 | ```
51 |
52 | Як і в PHP, підтримуються прості (списки) і асоціативні масиви:
53 |
54 | ##### Створення масиву з рядковими ключами
55 |
56 | ```zephir
57 | let elements = ["foo": "bar", "bar": "foo"];
58 | ```
59 |
60 | ##### Створення масиву з числовими ключами
61 |
62 | ```zephir
63 | let elements = [4: "bar", 8: "foo"];
64 | ```
65 |
66 | ##### Створення масиву з змішаними ключами (рядковими та числовими)
67 |
68 | ```zephir
69 | let elements = [4: "bar", "foo": 8];
70 | ```
71 |
72 |
73 |
74 | ## Оновлення масивів
75 |
76 | Масиви оновлюються таким же чином, як і PHP, використовуючи квадратні дужки:
77 |
78 | ##### Оновлення масиву з рядковим ключем
79 |
80 | ```zephir
81 | let elements["foo"] = "bar";
82 | ```
83 |
84 | ##### Оновлення масиву з числовим ключем
85 |
86 | ```zephir
87 | let elements[0] = "bar";
88 | ```
89 |
90 | ##### Оновлення багатовимірного масиву
91 |
92 | ```zephir
93 | let elements[0]["foo"] = "bar";
94 | let elements["foo"][0] = "bar";
95 | ```
96 |
97 |
98 |
99 | ## Додавання елементів
100 |
101 | Елементи можуть бути додані в кінці масиву наступним чином:
102 |
103 | ##### Додавання елемента до масиву
104 |
105 | ```zephir
106 | let elements[] = "bar";
107 | ```
108 |
109 |
110 |
111 | ## Читання елементів з масивів
112 |
113 | Прочитати елементи масиву можна наступним чином:
114 |
115 | ##### Отримання елемента, використовуючи рядковий ключ `foo`
116 |
117 | ```zephir
118 | let foo = elements["foo"];
119 | ```
120 |
121 | ##### Отримання елемента за допомогою числового ключа 0
122 |
123 | ```zephir
124 | let foo = elements[0];
125 | ```
--------------------------------------------------------------------------------
/uk-ua/closures.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Closures
8 |
9 | You can use closures (a.k.a. anonymous functions) in Zephir; these are PHP compatible and can be returned to the PHP userland:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Functional
15 | {
16 |
17 | public function map(array! data)
18 | {
19 | return function(number) {
20 | return number * number;
21 | };
22 | }
23 | }
24 | ```
25 |
26 | It also can be executed directly within Zephir, and passed as a parameter to other functions/methods:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Functional
32 | {
33 |
34 | public function map(array! data)
35 | {
36 | return data->map(function(number) {
37 | return number * number;
38 | });
39 | }
40 | }
41 | ```
42 |
43 | A short syntax is also available to define closures:
44 |
45 | ```zephir
46 | namespace MyLibrary;
47 |
48 | class Functional
49 | {
50 |
51 | public function map(array! data)
52 | {
53 | return data->map(number => number * number);
54 | }
55 | }
56 | ```
--------------------------------------------------------------------------------
/uk-ua/exceptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Exceptions
8 |
9 | Zephir implements exceptions at a very low level, providing similar behavior and functionality to PHP.
10 |
11 | When an exception is thrown, a `catch` block can be used to capture the exception and allow the developer to provide proper handling:
12 |
13 | Exceptions can be thrown inside the `try` block. Handling happens in the `catch` block, exactly as in PHP:
14 |
15 | ```zephir
16 | var e;
17 | try {
18 |
19 | throw new \Exception("This is an exception");
20 |
21 | } catch \Exception, e {
22 |
23 | echo e->getMessage();
24 | }
25 | ```
26 |
27 | Zephir also provides a "silent" `try` block, that simply ignores any exceptions produced within that block:
28 |
29 | ```zephir
30 | try {
31 | throw new \Exception("This is an exception");
32 | }
33 | ```
34 |
35 | If you don't need an exception variable when 'catch'ing, then you can safely not provide it:
36 |
37 | ```zephir
38 | try {
39 |
40 | throw new \Exception("This is an exception");
41 |
42 | } catch \Exception {
43 |
44 | echo "An exception occur!";
45 | }
46 | ```
47 |
48 | A single `catch` block can be used to catch multiple types of exception:
49 |
50 | ```zephir
51 | var e;
52 | try {
53 |
54 | throw new \Exception("This is an exception");
55 |
56 | } catch \RuntimeException|\Exception, e {
57 |
58 | echo e->getMessage();
59 | }
60 | ```
61 |
62 | Zephir allows you to throw literals or static typed variables as if they were the message of the exception:
63 |
64 | ```zephir
65 | // throw new \Exception("Test");
66 | throw "Test";
67 |
68 | // throw new \Exception((string) 't');
69 | throw 't';
70 |
71 | // throw new \Exception((string) 123);
72 | throw 123;
73 |
74 | // throw new \Exception((string) 123.123);
75 | throw 123.123;
76 | ```
77 |
78 | Zephir's exceptions provide the same methods to know where the exception happened that PHP's exceptions do. That is, `Exception::getFile()` and `Exception::getLine()` return the location in the Zephir code where the exception was thrown:
79 |
80 | ```bash
81 | Exception: The static method 'someMethod' does not exist on model 'Robots'
82 | File=phalcon/mvc/model.zep Line=4042
83 | #0 /home/scott/test.php(64): Phalcon\Mvc\Model::__callStatic('someMethod', Array)
84 | #1 /home/scott/test.php(64): Robots::someMethod()
85 | #2 {main}
86 | ```
--------------------------------------------------------------------------------
/uk-ua/functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Виклик функцій
8 |
9 | PHP has a rich library of functions that you can use within your extensions. To call a PHP function you simply use it as normal within your Zephir code:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Encoder
15 | {
16 | public function encode(var text)
17 | {
18 | if strlen(text) != 0 {
19 | return base64_encode(text);
20 | }
21 | return false;
22 | }
23 | }
24 | ```
25 |
26 | You can also call functions that are expected to exist in the PHP userland, but are not necessarily built in to PHP itself:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Encoder
32 | {
33 |
34 | public function encode(var text)
35 | {
36 | if strlen(text) != 0 {
37 | if function_exists("my_custom_encoder") {
38 | return my_custom_encoder(text);
39 | } else {
40 | return base64_encode(text);
41 | }
42 | }
43 | return false;
44 | }
45 | }
46 | ```
47 |
48 | Note that all PHP functions only receive and return dynamic variables. If you pass a static typed variable as a parameter, a temporary dynamic variable will automatically be used as a bridge in order to call the function:
49 |
50 | ```zephir
51 | namespace MyLibrary;
52 |
53 | class Encoder
54 | {
55 | public function encode(string text)
56 | {
57 | if strlen(text) != 0 {
58 | // an implicit dynamic variable is created to
59 | // pass the static typed 'text' as parameter
60 | return base64_encode(text);
61 | }
62 | return false;
63 | }
64 | }
65 | ```
66 |
67 | Similarly, functions return dynamic values, which cannot be directly assigned to static variables without the appropriate explicit cast:
68 |
69 | ```zephir
70 | namespace MyLibrary;
71 |
72 | class Encoder
73 | {
74 | public function encode(string text)
75 | {
76 | string encoded = "";
77 |
78 | if strlen(text) != 0 {
79 | let encoded = (string) base64_encode(text);
80 | return "(" . encoded . ")";
81 | }
82 | return false;
83 | }
84 | }
85 | ```
86 |
87 | Zephir also provides a way for you to call functions dynamically, such as:
88 |
89 | ```zephir
90 | namespace MyLibrary;
91 |
92 | class Encoder
93 | {
94 | public function encode(var callback, string text)
95 | {
96 | return {callback}(text);
97 | }
98 | }
99 | ```
--------------------------------------------------------------------------------
/uk-ua/globals.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Extension Globals
8 |
9 | PHP extensions provide a way to define globals within an extension. Reading/writing globals should be faster than any other global mechanisms (like static members). You can use extension globals to set up configuration options that change the behavior of your library.
10 |
11 | In Zephir, extension globals are restricted to simple scalar types like `int`/`bool`/`double`/`char`, etc. Complex types such as string/array/object/resource are not allowed here.
12 |
13 | You can enable extension globals by adding the following structure to your `config.json`:
14 |
15 | ```json
16 | {
17 | "globals": {
18 | "allow_some_feature": {
19 | "type": "bool",
20 | "default": true,
21 | "module": true
22 | },
23 | "number_times": {
24 | "type": "int",
25 | "default": 10
26 | },
27 | "some_component.my_setting_1": {
28 | "type": "bool",
29 | "default": true
30 | },
31 | "some_component.my_setting_2": {
32 | "type": "int",
33 | "default": 100
34 | }
35 | }
36 | }
37 | ```
38 |
39 | Each global has the following structure:
40 |
41 | ```json
42 | "": {
43 | "type": "",
44 | "default":
45 | }
46 | ```
47 |
48 | Compound (namespaced) globals have the following structure:
49 |
50 | ```json
51 | ".": {
52 | "type": "",
53 | "default":
54 | }
55 | ```
56 |
57 | The optional `module` key, if present, places that global's initialization process into the module-wide `GINIT` lifecycle event, which just means it will only be set up once per PHP process, rather than being reinitialized for every request, which is the default:
58 |
59 | ```json
60 | {
61 | "globals": {
62 | "allow_some_feature": {
63 | "type": "bool",
64 | "default": true,
65 | "module": true
66 | },
67 | "number_times": {
68 | "type": "int",
69 | "default": 10
70 | }
71 | }
72 | }
73 | ```
74 |
75 | In the example above, `allow_some_feature` is set up only once at startup; `number_times` is set up at the start of each request.
76 |
77 | Inside any method, you can read/write extension globals using the built-in functions `globals_get`/`globals_set`:
78 |
79 | ```zephir
80 | globals_set("allow_some_feature", true);
81 | let someFeature = globals_get("allow_some_feature");
82 | ```
83 |
84 | If you want to change these globals from PHP, a good option is include a method aimed at this:
85 |
86 | ```zephir
87 | namespace Test;
88 |
89 | class MyOptions
90 | {
91 |
92 | public static function setOptions(array options)
93 | {
94 | boolean someOption, anotherOption;
95 |
96 | if fetch someOption, options["some_option"] {
97 | globals_set("some_option", someOption);
98 | }
99 |
100 | if fetch anotherOption, options["another_option"] {
101 | globals_set("another_option", anotherOption);
102 | }
103 | }
104 | }
105 | ```
106 |
107 | Extension globals cannot be dynamically accessed, since the C code generated by the `globals_get`/`globals_set` optimizers must be resolved at compilation time:
108 |
109 | ```zephir
110 | let myOption = "someOption";
111 |
112 | // згенерує помилку компіляції
113 | let someOption = globals_get(myOption);
114 | ```
--------------------------------------------------------------------------------
/uk-ua/license.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # License
8 |
9 | MIT License
10 |
11 | Copyright (c) 2013-present Zephir Team
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/uk-ua/operator-precedence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Operator Precedence
8 | **Operator precedence** determines how operators are parsed. Operators with higher precedence become the operands of operators with lower precedence. For example, in the expression `1 + 5 * 3`, the answer is 16 and not 18 because the multiplication (`*`) operator has a higher precedence than the addition (`+`) operator. Parentheses may be used to force precedence, if necessary. For instance: `(1 + 5) * 3` evaluates to 18.
9 |
10 |
11 |
12 | ## Associativity
13 | When operators have equal precedence their **associativity** determines how the operators are grouped. For example `-` is _left-associative_, so `1 - 2 - 3` is grouped as `(1 - 2) - 3` and evaluates to `-4`. `=` on the other hand is _right-associative_, so `let a = b = c` is grouped as `let a = (b = c)`.
14 |
15 | Operators of equal precedence that are _non-associative_ cannot be used next to one another. For example:
16 | ```zep
17 | new new Foo();
18 | ```
19 | is illegal in Zephir, because the `new` is non-associative. At the moment, `new` is the only non-associative operator in Zephir.
20 |
21 | Use of parentheses, even when not strictly necessary, can often increase readability of the code, by making grouping explicit, rather than relying on the implicit operator precedence and associativity.
22 |
23 |
24 |
25 | ## Precedence Table
26 | The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides grouping.
27 |
28 | | Precedence | Оператори | Operator type | Associativity |
29 | | ---------- | -------------------------------- | ----------------------------------- | --------------- |
30 | | 1 | `->` | Member Access | right-to-left |
31 | | 2 | `~` | Bitwise NOT | right-to-left |
32 | | 3 | `!` | Logical NOT | right-to-left |
33 | | 4 | `new` | new | non-associative |
34 | | 5 | `clone` | clone | right-to-left |
35 | | 6 | `typeof` | Type-of | right-to-left |
36 | | 7 | `..`, `...` | Inclusive/exclusive range | left-to-right |
37 | | 8 | `isset`, `fetch`, `empty` | Exclusive range | right-to-left |
38 | | 9 | `*`, `/`, `%` | Multiplication, Division, Remainder | left-to-right |
39 | | 10 | `+`, `-`, `.` | Addition, Subtraction, Concat | left-to-right |
40 | | 11 | `<<`, `>>` | Bitwise shift left/right | left-to-right |
41 | | 12 | `<`, `<=`, `=>`, `>` | Comparison | left-to-right |
42 | | 13 | `==`, `!==`, `===`, `!==` | Comparison | left-to-right |
43 | | 14 | `&` | Bitwise AND, references | left-to-right |
44 | | 15 | `^` | Bitwise XOR | left-to-right |
45 | | 16 | `|` | Bitwise OR | left-to-right |
46 | | 17 | `instanceof` | Instance-of | left-to-right |
47 | | 18 | `&&` | Logical AND | left-to-right |
48 | | 19 | `||` | Logical OR | left-to-right |
49 | | 20 | `likely`, `unlikely` | Branch prediction | right-to-left |
50 | | 21 | `?` | Logical | right-to-left |
51 | | 21 | `=>` | Closure Arrow | right-to-left |
52 |
--------------------------------------------------------------------------------
/uk-ua/phpinfo.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Розділи в phpinfo()
8 |
9 | Як і більшість PHP-розширень, розширення написані на Zephir здатні показати інформацію у виводі [phpinfo()](https://php.net/manual/en/function.phpinfo.php). Зазвичай ця інформація відноситься до директив, даних оточення і т.д.
10 |
11 | Типово, кожне Zephir-розширення додає базову таблицю у вивід `phpinfo()`, яка показує версію розширення.
12 |
13 | Ви можете додати більше директив, додавши наступну конфігурацію в файл `config.json`:
14 |
15 | ```json
16 | "info": [
17 | {
18 | "header": ["Directive", "Value"],
19 | "rows": [
20 | ["setting1", "value1"],
21 | ["setting2", "value2"]
22 | ]
23 | },
24 | {
25 | "header": ["Directive", "Value"],
26 | "rows": [
27 | ["setting3", "value3"],
28 | ["setting4", "value4"]
29 | ]
30 | }
31 | ]
32 | ```
33 |
34 | Ця інформація буде показана наступним чином:
35 |
36 | 
--------------------------------------------------------------------------------
/uk-ua/sidebar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Welcome",
4 | "url": "welcome"
5 | },
6 | {
7 | "text": "Why Zephir",
8 | "url": "motivation"
9 | },
10 | {
11 | "text": "Представляємо Zephir",
12 | "url": "introduction"
13 | },
14 | {
15 | "text": "Встановлення",
16 | "url": "installation"
17 | },
18 | {
19 | "text": "Навчальний посібник",
20 | "url": "tutorial"
21 | },
22 | {
23 | "text": "Базовий синтаксис",
24 | "url": "language"
25 | },
26 | {
27 | "text": "Типи",
28 | "url": "types"
29 | },
30 | {
31 | "text": "Оператори",
32 | "url": "operators"
33 | },
34 | {
35 | "text": "Operator Precedence",
36 | "url": "operator-precedence"
37 | },
38 | {
39 | "text": "Масиви",
40 | "url": "arrays"
41 | },
42 | {
43 | "text": "Classes and objects",
44 | "url": "oop"
45 | },
46 | {
47 | "text": "Built-in methods",
48 | "url": "builtin-methods"
49 | },
50 | {
51 | "text": "Control structures",
52 | "url": "control-structures"
53 | },
54 | {
55 | "text": "Exceptions",
56 | "url": "exceptions"
57 | },
58 | {
59 | "text": "Calling functions",
60 | "url": "functions"
61 | },
62 | {
63 | "text": "Closures",
64 | "url": "closures"
65 | },
66 | {
67 | "text": "Custom optimizers",
68 | "url": "optimizers"
69 | },
70 | {
71 | "text": "Configuration file",
72 | "url": "config"
73 | },
74 | {
75 | "text": "Command Line",
76 | "url": "command-line"
77 | },
78 | {
79 | "text": "Lifecycle hooks",
80 | "url": "lifecycle"
81 | },
82 | {
83 | "text": "Extension globals",
84 | "url": "globals"
85 | },
86 | {
87 | "text": "phpinfo() sections",
88 | "url": "phpinfo"
89 | },
90 | {
91 | "text": "Static analysis",
92 | "url": "static-analysis"
93 | },
94 | {
95 | "text": "Optimizations",
96 | "url": "optimizations"
97 | },
98 | {
99 | "text": "Compiler warnings",
100 | "url": "warnings"
101 | },
102 | {
103 | "text": "License",
104 | "url": "license"
105 | }
106 | ]
107 |
--------------------------------------------------------------------------------
/uk-ua/static-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Static Analysis
8 |
9 | Zephir's compiler provides static analysis of the compiled code. The idea behind this feature is to help the developer to find potential problems and avoid unexpected behaviors, well before runtime.
10 |
11 |
12 |
13 | ## Conditional Unassigned Variables
14 |
15 | Static Analysis of assignments tries to identify if a variable is used before it's assigned:
16 |
17 | ```zephir
18 | class Utils
19 | {
20 | public function someMethod(b)
21 | {
22 | string a; char c;
23 |
24 | if b == 10 {
25 | let a = "hello";
26 | }
27 |
28 | //a could be unitialized here
29 | for c in a {
30 | echo c, PHP_EOL;
31 | }
32 | }
33 | }
34 | ```
35 |
36 | The above example illustrates a common situation. The variable `a` is assigned only when `b` is equal to 10, then it's required to use the value of this variable - but it could be uninitialized. Zephir detects this, automatically initializes the variable to an empty string, and generates a warning alerting the developer:
37 |
38 | ```bash
39 | Warning: Variable 'a' was assigned for the first time in conditional branch,
40 | consider initialize it in its declaration in
41 | /home/scott/test/test/utils.zep on 21 [conditional-initialization]
42 |
43 | for c in a {
44 | ```
45 |
46 | Finding such errors is sometimes tricky, however static analysis helps the programmer to find bugs in advance.
47 |
48 |
49 |
50 | ## Dead Code Elimination
51 |
52 | Zephir informs the developer about unreachable branches in the code and performs dead code elimination, which means it gets rid of all that code from the generated binary, since it cannot be executed anyway:
53 |
54 | ```zephir
55 | class Utils
56 | {
57 | public function someMethod(b)
58 | {
59 | if false {
60 | // This is never executed
61 | echo "hello";
62 | }
63 | }
64 | }
65 | ```
--------------------------------------------------------------------------------
/uk-ua/welcome.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'uk-ua'
4 | version: '0.12'
5 | ---
6 |
7 | # Вітаємо!
8 |
9 | Вас вітає Zephir — проект з відкритим вихідним кодом, високорівнева/предметно-орієнтована мова спроектована для полегшення створення й супроводу розширень для PHP з акцентом на тип та безпеку доступу до пам'яті.
10 |
11 |
12 |
13 | ## Деякі особливості
14 |
15 | Основними особливостями Zephir-у є:
16 |
17 | | Особливість | Опис |
18 | | --------------------------- | -------------------------------------------------- |
19 | | Система типізації | динамічна/статична |
20 | | Безпечний доступ до пам'яті | вказівники або пряме керування пам'яттю заборонені |
21 | | Компіляційна модель | компіляція виконується заздалегідь |
22 | | Модель пам'яті | свій збирач сміття |
23 |
24 |
25 |
26 | ## Скуштуйте
27 |
28 | Наступний код реєструє клас з методом, який фільтрує змінні, повертаючи лише їхні алфавітні символи:
29 |
30 | ```zephir
31 | namespace MyLibrary;
32 |
33 | /**
34 | * Фільтр
35 | */
36 | class Filter
37 | {
38 | /**
39 | * Фільтрує рядок, повертаючи його альфа-символи
40 | *
41 | * @param string str
42 | */
43 | public function alpha(string str)
44 | {
45 | char ch; string filtered = "";
46 |
47 | for ch in str {
48 | if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
49 | let filtered .= ch;
50 | }
51 | }
52 |
53 | return filtered;
54 | }
55 | }
56 | ```
57 |
58 | Цей клас можна виконати з PHP наступним чином:
59 |
60 | ```php
61 | alpha("01he#l.lo?/1"); // виведе hello
65 | ```
66 |
67 |
68 |
69 | ## Зовнішні посилання
70 |
71 | Нижче ми зібрали посилання на зовнішні ресурси, які можуть вас зацікавити:
72 |
73 | - [Система типізації](https://en.wikipedia.org/wiki/Type_system)
74 | - [Безпечний доступ до пам'яті](https://en.wikipedia.org/wiki/Memory_safety)
75 | - [Ahead-of-time (AOT) компіляція](https://en.wikipedia.org/wiki/Ahead-of-time_compilation)
76 | - [Керування пам’яттю](https://en.wikipedia.org/wiki/Memory_management)
--------------------------------------------------------------------------------
/zh-cn/arrays.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 数组
8 |
9 | Zephir中的数组操作提供了一种类似PHP [数组](https://www.php.net/manual/en/language.types.array.php)的方法。 An array is an implementation of a [hash table](https://en.wikipedia.org/wiki/Hash_table).
10 |
11 |
12 |
13 | ## 声明数组变量
14 |
15 | 数组变量可以使用关键字 "var" 或 "array" 来声明:
16 |
17 | ```zephir
18 | var a = []; // 数组变量,其类型可以改变
19 | array b = []; // 数组变量,其类型不能在执行过程中更改
20 | ```
21 |
22 |
23 |
24 | ## 创建数组
25 |
26 | 通过将其元素括在方括号中创建数组:
27 |
28 | ##### 创建空数组
29 |
30 | ```zephir
31 | let elements = [];
32 | ```
33 |
34 | ##### 创建包含元素的数组
35 |
36 | ```zephir
37 | let elements = [1, 3, 4];
38 | ```
39 |
40 | ##### 使用不同类型的元素创建数组
41 |
42 | ```zephir
43 | let elements = ["first", 2, true];
44 | ```
45 |
46 | ##### 多维数组
47 |
48 | ```zephir
49 | let elements = [[0, 1], [4, 5], [2, 3]];
50 | ```
51 |
52 | 就像 PHP,哈希或字典都支持的:
53 |
54 | ##### 使用字符串键创建哈希
55 |
56 | ```zephir
57 | let elements = ["foo": "bar", "bar": "foo"];
58 | ```
59 |
60 | ##### 使用数字键创建哈希
61 |
62 | ```zephir
63 | let elements = [4: "bar", 8: "foo"];
64 | ```
65 |
66 | ##### 使用字符串和数字键混合创建哈希
67 |
68 | ```zephir
69 | let elements = [4: "bar", "foo": 8];
70 | ```
71 |
72 |
73 |
74 | ## Updating arrays
75 |
76 | Arrays are updated in the same way as PHP, using square brackets:
77 |
78 | ##### 使用字符串键名更新数组
79 |
80 | ```zephir
81 | let elements["foo"] = "bar";
82 | ```
83 |
84 | ##### 使用数字键更新数组
85 |
86 | ```zephir
87 | let elements[0] = "bar";
88 | ```
89 |
90 | ##### 多维数组
91 |
92 | ```zephir
93 | let elements[0]["foo"] = "bar";
94 | let elements["foo"][0] = "bar";
95 | ```
96 |
97 |
98 |
99 | ## 追加元素
100 |
101 | 元素可以追加到数组的末尾, 如下所示:
102 |
103 | ##### 向数组追加一个元素
104 |
105 | ```zephir
106 | let elements[] = "bar";
107 | ```
108 |
109 |
110 |
111 | ## 从数组中读取元素
112 |
113 | 可以读取数组元素, 如下所示:
114 |
115 | ##### 使用字符串键获取元素 `foo`
116 |
117 | ```zephir
118 | let foo = elements["foo"];
119 | ```
120 |
121 | ##### 使用数字键0获取元素
122 |
123 | ```zephir
124 | let foo = elements[0];
125 | ```
--------------------------------------------------------------------------------
/zh-cn/builtin-methods.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 内建方法
8 |
9 | 如前所述,Zephir提倡面向对象编程。 与静态类型相关的变量也可以作为对象处理。
10 |
11 | 比较这两种方法:
12 |
13 | ```zephir
14 | public function binaryToHex(string! s) -> string
15 | {
16 | var o = "", n; char ch;
17 |
18 | for ch in range(0, strlen(s)) {
19 | let n = sprintf("%X", ch);
20 | if strlen(n) < 2 {
21 | let o .= "0" . n;
22 | } else {
23 | let o .= n;
24 | }
25 | }
26 | return o;
27 | }
28 | ```
29 |
30 | 与
31 |
32 | ```zephir
33 | public function binaryToHex(string! s) -> string
34 | {
35 | var o = "", n; char ch;
36 |
37 | for ch in range(0, s->length()) {
38 | let n = ch->toHex();
39 | if n->length() < 2 {
40 | let o .= "0" . n;
41 | } else {
42 | let o .= n;
43 | }
44 | }
45 | return o;
46 | }
47 | ```
48 |
49 | 它们都有相同的功能,但是第二个使用的是面向对象编程。 对静态类型变量调用方法对性能没有任何影响,因为Zephir在内部将代码从面向对象版本转换为过程版本。
50 |
51 |
52 |
53 | ## String
54 |
55 | 下面的字符串内置方法可用:
56 |
57 | | OO | 实际过程 | 说明 |
58 | | -------------------- | --------------------- | ---------------------- |
59 | | `s->format()` | `sprintf(s, "%s", x)` | 返回格式化的字符串 |
60 | | `s->index("foo")` | `strpos(s, "foo")` | 查找字符串中第一个出现的子字符串的位置 |
61 | | `s->length()` | `strlen(s)` | 获取字符串长度 |
62 | | `s->lower()` | `strtolower(s)` | 使字符串小写 |
63 | | `s->lowerfirst()` | `lcfirst(s)` | 使字符串的第一个字符小写 |
64 | | `s->md5()` | `md5(s)` | 计算字符串的 md5 哈希 |
65 | | `s->sha1()` | `sha1(s)` | 计算字符串的 sha1 哈希 |
66 | | `s->trim()` | `trim(s)` | 删除字符串的开头和结尾的空格 (或其他字符) |
67 | | `s->trimleft()` | `ltrim(s)` | 从字符串开头的条带空白 (或其他字符) |
68 | | `s->trimright()` | `rtrim(s)` | 删除字符串末端的空白字符(或者其他字符) |
69 | | `s->upper()` | `strtoupper(s)` | 使字符串大写 |
70 | | `s->upperfirst()` | `ucfirst(s)` | 使字符串的第一个字符大写 |
71 |
72 |
73 |
74 | ## Array
75 |
76 | 可用的数组内置方法如下:
77 |
78 | | OO | 实际过程 | 说明 |
79 | | -------------------- | ----------------------- | ----------------------- |
80 | | `a->combine(b)` | `array_combine(a, b)` | 通过使用一个数组表示键, 为其值创建另一个数组 |
81 | | `a->diff()` | `array_diff(a)` | 计算数组的差异 |
82 | | `a->flip()` | `array_flip(a)` | 将数组中的所有键与其关联的值交换 |
83 | | `a->hasKey()` | `array_key_exists(a)` | 检查数组中是否存在给定的键或索引 |
84 | | `a->intersect(b)` | `array_intersect(a, b)` | 计算数组的交集 |
85 | | `a->join(" ")` | `join(" ", a)` | 使用字符串联接数组元素 |
86 | | `a->keys()` | `array_keys(a)` | 返回数组的所有键或键的子集 |
87 | | `a->merge(b)` | `array_merge(a, b)` | 合并一个或多个数组 |
88 | | `a->pad()` | `array_pad(a, b)` | 以指定长度将一个值填充进数组 |
89 | | `a->rev()` | `array_reverse(a)` | 返回具有相反顺序的元素的数组 |
90 | | `a->reversed()` | `array_reverse(a)` | 返回具有相反顺序的元素的数组 |
91 | | `a->split()` | `array_chunk(a)` | 将数组拆分为多个块 |
92 | | `a->values()` | `array_values(a)` | 返回数组的所有值 |
93 | | `a->walk()` | `array_walk(a)` | 使用用户自定义函数对数组中的每个元素做回调处理 |
94 |
95 |
96 |
97 | ## Char
98 |
99 | 提供了以下字符内置方法:
100 |
101 | | OO | 实际过程 |
102 | | ---------------- | ------------------- |
103 | | `ch->toHex()` | `sprintf("%X", ch)` |
104 |
105 |
106 |
107 | ## Integer
108 |
109 | 以下是可用的整数内置方法:
110 |
111 | | OO | 实际过程 |
112 | | ------------- | -------- |
113 | | `i->abs()` | `abs(i)` |
--------------------------------------------------------------------------------
/zh-cn/closures.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 闭 包
8 |
9 | 您可以在Zephir中使用闭包(也称为匿名函数);这些是PHP兼容的,可以返回给PHP代码块:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Functional
15 | {
16 |
17 | public function map(array! data)
18 | {
19 | return function(number) {
20 | return number * number;
21 | };
22 | }
23 | }
24 | ```
25 |
26 | 它也可以直接在Zephir中执行,并作为参数传递给其他函数/方法:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Functional
32 | {
33 |
34 | public function map(array! data)
35 | {
36 | return data->map(function(number) {
37 | return number * number;
38 | });
39 | }
40 | }
41 | ```
42 |
43 | 一个简短的语法也可以用来定义闭包:
44 |
45 | ```zephir
46 | namespace MyLibrary;
47 |
48 | class Functional
49 | {
50 |
51 | public function map(array! data)
52 | {
53 | return data->map(number => number * number);
54 | }
55 | }
56 | ```
--------------------------------------------------------------------------------
/zh-cn/exceptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 例外情况
8 |
9 | Zephir以非常低的级别实现异常,为PHP提供类似的行为和功能。
10 |
11 | 抛出异常时,可以使用` catch `块来捕获异常并允许开发人员提供正确的处理:
12 |
13 | 可以在`try`语句中抛出异常。 和PHP一样,在`catch`中捕获异常并处理
14 |
15 | ```zephir
16 | var e;
17 | try {
18 |
19 | throw new \Exception("This is an exception");
20 |
21 | } catch \Exception, e {
22 |
23 | echo e->getMessage();
24 | }
25 | ```
26 |
27 | Zephir 还提供了一个“安静”`try`语句,用来忽略产生的任何异常:
28 |
29 | ```zephir
30 | try {
31 | throw new \Exception("This is an exception");
32 | }
33 | ```
34 |
35 | 如果在<0>catch0>中不处理异常,可以不提供异常变量:
36 |
37 | ```zephir
38 | try {
39 |
40 | throw new \Exception("This is an exception");
41 |
42 | } catch \Exception {
43 |
44 | echo "An exception occur!";
45 | }
46 | ```
47 |
48 | 在`catch`中捕获多个异常:
49 |
50 | ```zephir
51 | var e;
52 | try {
53 |
54 | throw new \Exception("This is an exception");
55 |
56 | } catch \RuntimeException|\Exception, e {
57 |
58 | echo e->getMessage();
59 | }
60 | ```
61 |
62 | Zephir允许您抛出文字或静态类型变量,就像它们是异常的消息一样:
63 |
64 | ```zephir
65 | // throw new \Exception("Test");
66 | throw "Test";
67 |
68 | // throw new \Exception((string) 't');
69 | throw 't';
70 |
71 | // throw new \Exception((string) 123);
72 | throw 123;
73 |
74 | // throw new \Exception((string) 123.123);
75 | throw 123.123;
76 | ```
77 |
78 | Zephir's exceptions provide the same methods to know where the exception happened that PHP's exceptions do. That is, `Exception::getFile()` and `Exception::getLine()` return the location in the Zephir code where the exception was thrown:
79 |
80 | ```bash
81 | Exception: The static method 'someMethod' does not exist on model 'Robots'
82 | File=phalcon/mvc/model.zep Line=4042
83 | #0 /home/scott/test.php(64): Phalcon\Mvc\Model::__callStatic('someMethod', Array)
84 | #1 /home/scott/test.php(64): Robots::someMethod()
85 | #2 {main}
86 | ```
--------------------------------------------------------------------------------
/zh-cn/functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 调用函数
8 |
9 | PHP有一个丰富的函数库,您可以在扩展中使用它们。 要调用PHP函数,只需在Zephir代码中正常使用它:
10 |
11 | ```zephir
12 | namespace MyLibrary;
13 |
14 | class Encoder
15 | {
16 | public function encode(var text)
17 | {
18 | if strlen(text) != 0 {
19 | return base64_encode(text);
20 | }
21 | return false;
22 | }
23 | }
24 | ```
25 |
26 | 您还可以调用预期存在于PHP用户区中的函数,但不一定是内置于PHP本身:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Encoder
32 | {
33 |
34 | public function encode(var text)
35 | {
36 | if strlen(text) != 0 {
37 | if function_exists("my_custom_encoder") {
38 | return my_custom_encoder(text);
39 | } else {
40 | return base64_encode(text);
41 | }
42 | }
43 | return false;
44 | }
45 | }
46 | ```
47 |
48 | 请注意,所有PHP函数仅接收和返回动态变量。 如果将静态类型变量作为参数传递,则临时动态变量将自动用作桥接器以调用该函数:
49 |
50 | ```zephir
51 | namespace MyLibrary;
52 |
53 | class Encoder
54 | {
55 | public function encode(string text)
56 | {
57 | if strlen(text) != 0 {
58 | // an implicit dynamic variable is created to
59 | // pass the static typed 'text' as parameter
60 | return base64_encode(text);
61 | }
62 | return false;
63 | }
64 | }
65 | ```
66 |
67 | 类似地,函数返回动态值,如果没有适当的显式强制转换,则无法直接将其分配给静态变量:
68 |
69 | ```zephir
70 | namespace MyLibrary;
71 |
72 | class Encoder
73 | {
74 | public function encode(string text)
75 | {
76 | string encoded = "";
77 |
78 | if strlen(text) != 0 {
79 | let encoded = (string) base64_encode(text);
80 | return "(" . encoded . ")";
81 | }
82 | return false;
83 | }
84 | }
85 | ```
86 |
87 | Zephir还为您提供了一种动态调用函数的方法,例如:
88 |
89 | ```zephir
90 | namespace MyLibrary;
91 |
92 | class Encoder
93 | {
94 | public function encode(var callback, string text)
95 | {
96 | return {callback}(text);
97 | }
98 | }
99 | ```
--------------------------------------------------------------------------------
/zh-cn/globals.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 全局扩展
8 |
9 | PHP扩展提供了一种在扩展中定义全局变量的方法。 读/写全局变量应该比任何其他全局机制(如静态成员)更快。 您可以使用扩展全局变量来设置更改库行为的配置选项。
10 |
11 | 在Zephir中,扩展全局变量仅限于简单的标量类型,如` int 0> / bool 0> / double 0> / char 0>等。 此处不允许使用复杂类型,例如字符串/数组/对象/资源。
12 |
13 | 您可以通过将以下结构添加到 config.json `来启用扩展全局变量:
14 |
15 | ```json
16 | {
17 | "globals": {
18 | "allow_some_feature": {
19 | "type": "bool",
20 | "default": true,
21 | "module": true
22 | },
23 | "number_times": {
24 | "type": "int",
25 | "default": 10
26 | },
27 | "some_component.my_setting_1": {
28 | "type": "bool",
29 | "default": true
30 | },
31 | "some_component.my_setting_2": {
32 | "type": "int",
33 | "default": 100
34 | }
35 | }
36 | }
37 | ```
38 |
39 | 每个全局具有以下结构:
40 |
41 | ```json
42 | "": {
43 | "type": "",
44 | "default":
45 | }
46 | ```
47 |
48 | 复合(命名空间)全局变量具有以下结构:
49 |
50 | ```json
51 | ".": {
52 | "type": "",
53 | "default":
54 | }
55 | ```
56 |
57 | 可选的`module 0>键(如果存在)将全局的初始化过程放入模块范围的 GINIT 0>生命周期事件中,这意味着它只会在每个PHP进程中设置一次, 而不是为每个请求重新初始化,这是默认值:
58 |
59 | {
60 | "globals": {
61 | "allow_some_feature": {
62 | "type": "bool",
63 | "default": true,
64 | "module": true
65 | },
66 | "number_times": {
67 | "type": "int",
68 | "default": 10
69 | }
70 | }
71 | }
72 | `
73 |
74 | 在上面的例子中,`allow_some_feature`在启动时只设置一次;`number_times`是在每个请求开始时设置的。
75 |
76 | 在任何方法中,您可以使用内置函数` globals_get ` / ` globals_set `读/写扩展全局变量:
77 |
78 | ```zephir
79 | globals_set("allow_some_feature", true);
80 | let someFeature = globals_get("allow_some_feature");
81 | ```
82 |
83 | 如果你想从PHP中改变这些全局变量,一个好的选择是包含一个针对这个的方法:
84 |
85 | ```zephir
86 | namespace Test;
87 |
88 | class MyOptions
89 | {
90 |
91 | public static function setOptions(array options)
92 | {
93 | boolean someOption, anotherOption;
94 |
95 | if fetch someOption, options["some_option"] {
96 | globals_set("some_option", someOption);
97 | }
98 |
99 | if fetch anotherOption, options["another_option"] {
100 | globals_set("another_option", anotherOption);
101 | }
102 | }
103 | }
104 | ```
105 |
106 | 不能动态访问扩展全局, 因为 `globals_get`/`globals_set` 优化器生成的 c 代码必须在编译时解析:
107 |
108 | ```zephir
109 | let myOption = "someOption";
110 |
111 | // 将抛出编译器异常
112 | let someOption = globals_get(myOption);
113 | ```
--------------------------------------------------------------------------------
/zh-cn/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # Zephir 简介
8 |
9 | Zephir 是一种语言, 它能够满足 php 开发人员的主要需求, 他们试图编写和编译可由 php 执行的代码。 它是动态的/静态类型的, 它的一些功能为 php 开发人员所熟悉。
10 |
11 | Zephir 这个名字是单词 z (end) e (ngine)/ph (p)/i (nte) r (mediate) 的收缩。 While this suggests that the pronunciation should be "zephyr", the creators of Zephir actually pronounce it [zaefire](https://translate.google.com/#en/en/zaefire).
12 |
13 |
14 |
15 | ## Hello World!
16 |
17 | 每种语言都有自己的 "Hello World!" 示例。 在 Zephir 中, 这个介绍性示例展示了该语言的一 些重要功能。
18 |
19 | Zephir 中的代码必须放在类中。 该语言旨在创建面向对象的库框架, 因此不允许在类之外使用代码。 此外, 还需要命名空间:
20 |
21 | ```zephir
22 | namespace Test;
23 |
24 | /**
25 | * This is a sample class
26 | */
27 | class Hello
28 | {
29 | /**
30 | * This is a sample method
31 | */
32 | public function say()
33 | {
34 | echo "Hello World!";
35 | }
36 | }
37 | ```
38 |
39 | 编译此类后, 它将生成以下代码, 该代码由 gcc/clang/vc ++ 透明地编译:
40 |
41 | ```c
42 | #ifdef HAVE_CONFIG_H
43 | #include "config.h"
44 | #endif
45 |
46 | #include "php.h"
47 | #include "php_test.h"
48 | #include "test.h"
49 |
50 | #include "kernel/main.h"
51 |
52 | /**
53 | * This is a sample class
54 | */
55 | ZEPHIR_INIT_CLASS(Test_Hello) {
56 | ZEPHIR_REGISTER_CLASS(Test, Hello, hello, test_hello_method_entry, 0);
57 | return SUCCESS;
58 | }
59 |
60 | /**
61 | * This is a sample method
62 | */
63 | PHP_METHOD(Test_Hello, say) {
64 | php_printf("%s", "Hello World!");
65 | }
66 | ```
67 |
68 | 实际上, 使用 Zephir 的开发人员必须知道甚至理解 c, 这是不希望的。但是, 如果您对编译器、php 内部或 c 语言本身有任何经验, 这将使您更清楚地了解在使用 Zephir 时内部发生的情况。
69 |
70 |
71 |
72 | ## 一个 Zephir 的尝试
73 |
74 | 在下面的例子中,我们将描述足够多的细节来理解发生了什么。 目标是让您了解Zephir中的编程是什么样子的。 我们将在后面的章节中探索细节的特性。
75 |
76 | 下面的例子很简单; 它实现了一个类和一个方法,以及一个检查数组类型的小程序。
77 |
78 | 让我们详细检查代码,以便开始学习Zephir语法。 在短短几行代码中有很多细节! 我们将在这里解释其大意:
79 |
80 | ```zephir
81 | namespace Test;
82 |
83 | /**
84 | * MyTest (test/mytest.zep)
85 | */
86 | class MyTest
87 | {
88 | public function someMethod()
89 | {
90 | /* Variables must be declared */
91 | var myArray;
92 | int i = 0, length;
93 |
94 | /* Create an array */
95 | let myArray = ["hello", 0, 100.25, false, null];
96 |
97 | /* Count the array into a 'int' variable */
98 | let length = count(myArray);
99 |
100 | /* Print value types */
101 | while i < length {
102 | echo typeof myArray[i], "\n";
103 | let i++;
104 | }
105 |
106 | return myArray;
107 | }
108 | }
109 | ```
110 |
111 | 在该方法中,第一行使用`var`和`int`关键字。 用于在局部作用域中声明一个变量。 方法中使用的每个变量都必须使用其各自的类型声明。 这个声明不是可选的——它帮助编译器警告您输入错误的变量,或者警告您使用超出范围的变量,这通常会导致运行时错误。
112 |
113 | 使用关键字`var`声明动态变量。 可以将这些变量分配并重新分配给不同的类型。 另一方面, `i` 和 `length` 变量是静态类型的整数变量, 在整个程序执行中只能有整数值。
114 |
115 | 与 php 不同的是, 你不需要在变量名前面放一个美元符号 ($)。
116 |
117 | Zephir 遵循与 java、c#、c++ 等相同的注释约定。 `//评论 0 > 到了一行的末尾, 而 /* 注释 */` 可以跨越线边界。
118 |
119 | 默认情况下, 变量是不可变的。 这意味着 Zephir 预计大多数变量将保持不变。 保持其初始值的变量可以由编译器优化为静态常量。 当需要更改变量值时, 必须使用关键字 `let`:
120 |
121 | ```zephir
122 | /* Create an array */
123 | let myArray = ["hello", 0, 100.25, false, null];
124 | ```
125 |
126 | 默认情况下, 数组是动态类型的, 就像 php 中一样-它们可能包含不同类型的值。 PHP的函数可以在Zephir代码中调用。 在下一个示例中, 调用函数 `count`, 但编译器可以执行优化, 如避免此调用, 因为它已经知道数组的大小:
127 |
128 | ```zephir
129 | /* Count the array into a 'int' variable */
130 | let length = count(myArray);
131 | ```
132 |
133 | 控件流语句中的括号是可选的。 如果你觉得这样做更舒服,你可以使用它们,但不是必须的。
134 |
135 | ```zephir
136 | while i < length {
137 | echo typeof myArray[i], "\n";
138 | let i++;
139 | }
140 | ```
141 |
142 | 由于PHP只处理动态变量,因此方法总是返回动态变量。 这意味着如果返回静态类型的变量,在PHP端您将得到一个可用于PHP代码的动态变量。 注意,内存是由编译器自动管理的,类似于PHP的管理方式,所以您不需要像在C中那样分配或释放内存。
--------------------------------------------------------------------------------
/zh-cn/language.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 基本语法
8 |
9 | 在本章中, 我们将讨论文件和命名空间、变量声明、杂项语法约定以及其他几个一般概念的组织。
10 |
11 |
12 |
13 | ## 在文件和命名空间中组织代码
14 |
15 | 在 php 中, 您可以将代码放置在任何文件中, 而不需要特定的结构。 在 Zephir中, 每个文件都必须包含一个类 (并且只有一个类)。 每个类都必须有一个命名空间, 并且目录结构必须与所使用的类和命名空间的名称相匹配。 (这类似于 psr-4 自动加载约定, 只是它是由语言本身强制执行的。
16 |
17 | 例如, 给定以下结构, 每个文件中的类必须是:
18 |
19 | ```bash
20 | mylibrary/
21 | router/
22 | exception.zep #
23 | router.zep # MyLibrary\Router
24 | ```
25 |
26 | Class in `mylibrary/router.zep`:
27 |
28 | ```zephir
29 | namespace MyLibrary;
30 |
31 | class Router
32 | {
33 |
34 | }
35 | ```
36 |
37 | Class in `mylibrary/router/exception.zep`:
38 |
39 | ```zephir
40 | namespace MyLibrary\Router;
41 |
42 | class Exception extends \Exception
43 | {
44 |
45 | }
46 | ```
47 |
48 | 如果文件或类不在预期文件中, 则 Zephir 将引发编译器异常, 反之亦然。
49 |
50 |
51 |
52 | ## 指令分离
53 |
54 | 您可能已经注意到, 前一章中的代码示例中很少有分号。 您可以使用分号分隔语句和表达式, 如 java、c/c ++、php 和类似语言:
55 |
56 | ```zephir
57 | myObject->myMethod(1, 2, 3); echo "world";
58 | ```
59 |
60 |
61 |
62 | ## 注释
63 |
64 | Zephir 支持 "c"/"c++" 注释。 这是行注释 `// ...`, 这是多行注释 `/* ... */`:
65 |
66 | ```zephir
67 | // this is a one line comment
68 |
69 | /**
70 | * multi-line comment
71 | */
72 | ```
73 |
74 | 在大多数语言中,注释只是编译器/解释器忽略的文本。 在Zephir中,多行注释也用作docblock,它们被导出到生成的代码中,因此它们是语言的一部分!
75 |
76 | 如果docblock不在预期的位置,编译器将抛出异常。
77 |
78 |
79 |
80 | ## 变量声明
81 |
82 | 在Zephir中,必须声明给定范围中使用的所有变量。 这为编译器执行优化和验证提供了重要信息。 变量必须是唯一的标识符,它们不能是保留字。
83 |
84 | ```zephir
85 | // 在同一指令中声明相同类型的变量
86 | var a, b, c;
87 |
88 | // 在单独的行中声明每个变量
89 | var a;
90 | var b;
91 | var c;
92 | ```
93 |
94 | 变量可以选择有一个初始兼容的默认值:
95 |
96 | ```zephir
97 | // 使用默认值声明变量
98 | var a = "hello", b = 0, c = 1.0;
99 | int d = 50; bool some = true;
100 | ```
101 |
102 | 变量名区分大小写,以下变量不同:
103 |
104 | ```zephir
105 | // 不同的变量
106 | var somevalue, someValue, SomeValue;
107 | ```
108 |
109 |
110 |
111 | ## 变量作用域
112 |
113 | 所有声明的变量都局部作用于声明它们的方法:
114 |
115 | ```zephir
116 | namespace Test;
117 |
118 | class MyClass
119 | {
120 | public function someMethod1()
121 | {
122 | int a = 1, b = 2;
123 | return a + b;
124 | }
125 |
126 | public function someMethod2()
127 | {
128 | int a = 3, b = 4;
129 | return a + b;
130 | }
131 | }
132 | ```
133 |
134 |
135 |
136 | ## 超全局
137 |
138 | Zephir不支持全局变量——不允许从PHP代码块访问全局变量。 然而,您可以访问PHP的超全局变量,如下所示:
139 |
140 | ```zephir
141 | // 从_POST获取值
142 | let price = _POST["price"];
143 |
144 | // 从_SERVER读取值
145 | let requestMethod = _SERVER["REQUEST_METHOD"];
146 | ```
147 |
148 |
149 |
150 | ## 本地符号表
151 |
152 | PHP中的每个方法或上下文都有一个符号表,允许您以非常动态的方式编写变量:
153 |
154 | ```php
155 |
20 |
21 | ## initializers
22 |
23 | `initializers` 块如下所示:
24 |
25 | ```json
26 | {
27 | "initializers": [
28 | {
29 | "globals": [
30 | {
31 | "include": "my/awesome/library.h",
32 | "code": "setup_globals_deps(TSRMLS_C)"
33 | }
34 | ],
35 | "module": [
36 | {
37 | "include": "my/awesome/library.h",
38 | "code": "setup_module_deps(TSRMLS_C)"
39 | }
40 | ],
41 | "request": [
42 | {
43 | "include": "my/awesome/library.h",
44 | "code": "some_c_function(TSRMLS_C)"
45 | },
46 | {
47 | "include": "my/awful/library.h",
48 | "code": "some_other_c_function(TSRMLS_C)"
49 | }
50 | ]
51 | }
52 | ]
53 | }
54 | ```
55 |
56 | 这个块负责定义到上面图中显示的Init事件的钩子。 其中有三个:`globals`用于设置全局变量空间;`module`用于设置扩展本身需要功能的任何内容;`request`用于设置扩展来处理单个请求。
57 |
58 |
59 |
60 | ## destructors
61 |
62 | `destructors` 块如下所示:
63 |
64 | ```json
65 | {
66 | "destructors": [
67 | {
68 | "request": [
69 | {
70 | "include": "my/awesome/library.h",
71 | "code": "c_function_for_shutting_down(TSRMLS_C)"
72 | },
73 | {
74 | "include": "my/awful/library.h",
75 | "code": "some_other_c_function_than_the_other_ones(TSRMLS_C)"
76 | }
77 | ],
78 | "post-request": [
79 | {
80 | "include": "my/awesome/library.h",
81 | "code": "c_function_for_cleaning_up_after_the_response_is_sent(TSRMLS_C)"
82 | }
83 | ],
84 | "module": [
85 | {
86 | "include": "my/awesome/library.h",
87 | "code": "release_module_deps(TSRMLS_C)"
88 | }
89 | ],
90 | "globals": [
91 | {
92 | "include": "my/awesome/library.h",
93 | "code": "release_globals_deps(TSRMLS_C)"
94 | }
95 | ]
96 | }
97 | ]
98 | }
99 | ```
100 |
101 | 正如 `initializers` 块负责定义上图中显示的 init 事件中的挂钩一样, *this* 块负责定义关机事件中的挂钩。 有四个:`request`响应之前敲定任何数据发送到客户端,`post-request`清理响应被发送后,`module0 >模块扩展后的清理本身PHP进程关闭之前, 和globals`清理全局变量空间。
--------------------------------------------------------------------------------
/zh-cn/motivation.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 为什么选择 Zephir?
8 |
9 | 今天的 php 应用程序必须平衡许多问题, 包括稳定性、性能和功能。 每个 php 应用程序都基于一组公共组件, 这些组件也是许多其他应用程序的基础。
10 |
11 | 这些常见组件是库、框架或两者的组合。 一旦安装, 框架很少改变, 并且作为应用程序的基础, 它们必须具有很高的功能, 而且速度也非常快。
12 |
13 | 获得快速和可靠的库可能会很复杂, 因为通常在它们上实现了高水平的抽象。 考虑到基础库或框架很少更改的限制, 可以利用编译来提高性能和资源消耗, 构建提供此功能的扩展。
14 |
15 | 使用 Zephir, 您可以实现可从 php 使用的面向对象的库/框架/应用程序, 使您的应用程序更快, 同时改善用户体验。
16 |
17 |
18 |
19 | ## 如果你是一个 php 程序员...
20 |
21 | PHP是web应用程序开发中最流行的语言之一。 像PHP这样的动态类型和解释语言由于其灵活性提供了非常高的生产力。
22 |
23 | 由于是第4版,PHP基于Zend引擎实现。 这是一个虚拟机,它通过字节码表示来执行PHP代码。 Zend 引擎几乎出现在世界上所有PHP安装中。 使用Zephir,您可以为在Zend引擎下运行的PHP创建扩展。
24 |
25 | PHP是Zephir的宿主,显然它们有很多相似之处; 然而,它们有重要的区别,使得Zephir有了自己的个性。 例如,Zephir更加严格,由于编译步骤的原因,它可能使您的生产率低于PHP。
26 |
27 |
28 |
29 | ## 如果你是一个 C 程序员..。
30 |
31 | C语言是有史以来最强大、最流行的语言之一。 实际上,PHP是用C编写的,这也是PHP扩展可用的原因之一。 C允许您自由地管理内存,使用低级类型,甚至内联程序集例程。
32 |
33 | 然而,与PHP或Zephir相比,在C中开发大型应用程序所花费的时间要比预期的长得多,而且如果您不是经验丰富的开发人员,有些错误可能很难发现。
34 |
35 | Zephir是为了安全而设计的,因此它不实现指针或手动内存管理,因此如果您是C程序员,您会觉得Zephir不如C程序员强大,但比C程序员更友好。
36 |
37 |
38 |
39 | ## 编译 vs 解释
40 |
41 | 编译通常会减慢开发速度; 在运行代码之前,您需要更多的耐心来编译代码。 另一方面,解释倾向于降低代码性能,以提高开发人员的工作效率。 也就是说,在某些情况下,解释代码和编译代码的速度没有明显的区别。
42 |
43 | Zephir需要编译您的代码,但其功能是从PHP中使用的,PHP是经过解释的。
44 |
45 | 一旦编译了代码,就不需要再这样做了。 每次运行解释代码时都会对其进行解释。 开发人员可以决定其应用程序的哪些部分应位于 Zephir 中, 而哪些部分不应该在 Zephir 中。
46 |
47 |
48 |
49 | ## 静态类型化 vs 动态类型化的语言
50 |
51 | 一般来说, 在静态类型化语言中, 变量在其生存期内绑定到特定类型。 它的类型不能更改, 它只能引用与类型兼容的实例和操作。 使用了类似 c/c ++ 等语言的方案:
52 |
53 | ```zephir
54 | int a = 0;
55 | a = "hello"; // not allowed
56 | ```
57 |
58 | 在动态类型中, 类型绑定到值, 而不是变量。 因此,一个变量可以引用一个类型的值,然后被重新分配到一个不相关类型的值。 Javascript/PHP 是一个动态类型语言的例子:
59 |
60 | ```zephir
61 | var a = 0;
62 | a = "hello"; // allowed
63 | ```
64 |
65 | 尽管动态语言具有生产率优势,但它可能不是所有应用程序的最佳选择,尤其是对于非常大的代码库和高性能应用程序。
66 |
67 | 优化动态语言(如PHP) 的性能比优化静态语言(如c) 更具有挑战性。在静态语言中,优化器可以利用附加在变量本身上的类型信息来做出决策。 在动态语言中, 优化器可用的此类线索较少, 因此优化选择更加困难。
68 |
69 | 虽然最近在动态语言优化方面取得的进展很有希望 (如 jit 编译), 但它们落后于静态语言的最新发展。 因此, 如果您需要非常高性能, 静态语言可能是更安全的选择。
70 |
71 | 静态语言的另一个小好处是编译器执行的额外检查。 编译器找不到逻辑错误, 这些错误的重要性要大得多, 但编译器可以提前找到仅在运行时动态语言中才能找到的错误。
72 |
73 | Zephir 是静态和动态类型化的, 允许您在可能的情况下利用这两种方法。
74 |
75 |
76 |
77 | ## 编译方案
78 |
79 | Zephir提供本机代码生成(目前通过编译到C)。 像gcc/clang/vc++这样的编译器会优化并将代码编译成机器代码。 下图显示了该过程的工作原理:
80 |
81 | 
82 |
83 | 除了Zephir提供的优化之外,随着时间的推移,编译器已经实现并成熟了许多优化,这些优化可以提高编译应用程序的性能:
84 |
85 | * [GCC 优化](https://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Optimize-Options.html)
86 | * [LLVM 传递](https://llvm.org/docs/Passes.html)
87 | * [Visual C/C++ 优化](https://msdn.microsoft.com/en-us/library/k1ack8f1.aspx)
88 |
89 |
90 |
91 | ## 代码保护
92 |
93 | 在某些情况下,编译不会显著提高性能。 这可能是因为瓶颈位于应用程序的I/O绑定部分(很可能),而不是计算/内存绑定。 然而,编译代码也可以为您的应用程序带来一定程度的知识保护。 使用Zephir,生成本地二进制文件,您还可以将原始代码“隐藏”给用户或客户。
94 |
95 |
96 |
97 | ## 结语
98 |
99 | Zephir的创建不是为了替代PHP或C. 相反,我们认为它是对它们的补充,允许PHP开发人员尝试进行代码编译和静态类型。 Zephir试图将C和PHP世界的优点结合起来,寻找使应用程序更快的机会。
--------------------------------------------------------------------------------
/zh-cn/operator-precedence.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # Operator Precedence
8 | **Operator precedence** determines how operators are parsed. Operators with higher precedence become the operands of operators with lower precedence. For example, in the expression `1 + 5 * 3`, the answer is 16 and not 18 because the multiplication (`*`) operator has a higher precedence than the addition (`+`) operator. Parentheses may be used to force precedence, if necessary. For instance: `(1 + 5) * 3` evaluates to 18.
9 |
10 |
11 |
12 | ## Associativity
13 | When operators have equal precedence their **associativity** determines how the operators are grouped. For example `-` is _left-associative_, so `1 - 2 - 3` is grouped as `(1 - 2) - 3` and evaluates to `-4`. `=` on the other hand is _right-associative_, so `let a = b = c` is grouped as `let a = (b = c)`.
14 |
15 | Operators of equal precedence that are _non-associative_ cannot be used next to one another. For example:
16 | ```zep
17 | new new Foo();
18 | ```
19 | is illegal in Zephir, because the `new` is non-associative. At the moment, `new` is the only non-associative operator in Zephir.
20 |
21 | Use of parentheses, even when not strictly necessary, can often increase readability of the code, by making grouping explicit, rather than relying on the implicit operator precedence and associativity.
22 |
23 |
24 |
25 | ## Precedence Table
26 | The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides grouping.
27 |
28 | | Precedence | 运算符 | Operator type | Associativity |
29 | | ---------- | -------------------------------- | ----------------------------------- | --------------- |
30 | | 1 | `->` | Member Access | right-to-left |
31 | | 2 | `~` | Bitwise NOT | right-to-left |
32 | | 3 | `!` | Logical NOT | right-to-left |
33 | | 4 | `new` | new | non-associative |
34 | | 5 | `clone` | clone | right-to-left |
35 | | 6 | `typeof` | Type-of | right-to-left |
36 | | 7 | `..`, `...` | Inclusive/exclusive range | left-to-right |
37 | | 8 | `isset`, `fetch`, `empty` | Exclusive range | right-to-left |
38 | | 9 | `*`, `/`, `%` | Multiplication, Division, Remainder | left-to-right |
39 | | 10 | `+`, `-`, `.` | Addition, Subtraction, Concat | left-to-right |
40 | | 11 | `<<`, `>>` | Bitwise shift left/right | left-to-right |
41 | | 12 | `<`, `<=`, `=>`, `>` | Comparison | left-to-right |
42 | | 13 | `==`, `!==`, `===`, `!==` | Comparison | left-to-right |
43 | | 14 | `&` | Bitwise AND, references | left-to-right |
44 | | 15 | `^` | Bitwise XOR | left-to-right |
45 | | 16 | `|` | Bitwise OR | left-to-right |
46 | | 17 | `instanceof` | Instance-of | left-to-right |
47 | | 18 | `&&` | Logical AND | left-to-right |
48 | | 19 | `||` | Logical OR | left-to-right |
49 | | 20 | `likely`, `unlikely` | Branch prediction | right-to-left |
50 | | 21 | `?` | Logical | right-to-left |
51 | | 21 | `=>` | Closure Arrow | right-to-left |
52 |
--------------------------------------------------------------------------------
/zh-cn/phpinfo.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # phpinfo () 部分
8 |
9 | 与大多数扩展一样, Zephir 扩展能够在 [phpinfo()](https://php.net/manual/en/function.phpinfo.php) 输出中显示信息。 这些信息通常与指令、环境数据等有关。
10 |
11 | 默认情况下, 每个 Zephir扩展都会自动向显示扩展版本和扩展所支持的任何 ini 选项的 `phpinfo()` 输出中添加一个基本表。
12 |
13 | 通过向 `config.json` 文件中添加以下配置, 可以添加更多指令:
14 |
15 | ```json
16 | "info": [
17 | {
18 | "header": ["Directive", "Value"],
19 | "rows": [
20 | ["setting1", "value1"],
21 | ["setting2", "value2"]
22 | ]
23 | },
24 | {
25 | "header": ["Directive", "Value"],
26 | "rows": [
27 | ["setting3", "value3"],
28 | ["setting4", "value4"]
29 | ]
30 | }
31 | ]
32 | ```
33 |
34 | 此信息将如下所示:
35 |
36 | 
--------------------------------------------------------------------------------
/zh-cn/sidebar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Welcome",
4 | "url": "welcome"
5 | },
6 | {
7 | "text": "Why Zephir",
8 | "url": "motivation"
9 | },
10 | {
11 | "text": "Zephir 简介",
12 | "url": "introduction"
13 | },
14 | {
15 | "text": "安装",
16 | "url": "installation"
17 | },
18 | {
19 | "text": "教程",
20 | "url": "tutorial"
21 | },
22 | {
23 | "text": "基本语法",
24 | "url": "language"
25 | },
26 | {
27 | "text": "类型",
28 | "url": "types"
29 | },
30 | {
31 | "text": "运算符",
32 | "url": "operators"
33 | },
34 | {
35 | "text": "Operator Precedence",
36 | "url": "operator-precedence"
37 | },
38 | {
39 | "text": "数组",
40 | "url": "arrays"
41 | },
42 | {
43 | "text": "Classes and objects",
44 | "url": "oop"
45 | },
46 | {
47 | "text": "Built-in methods",
48 | "url": "builtin-methods"
49 | },
50 | {
51 | "text": "Control structures",
52 | "url": "control-structures"
53 | },
54 | {
55 | "text": "例外情况",
56 | "url": "exceptions"
57 | },
58 | {
59 | "text": "Calling functions",
60 | "url": "functions"
61 | },
62 | {
63 | "text": "闭 包",
64 | "url": "closures"
65 | },
66 | {
67 | "text": "自定义优化器",
68 | "url": "optimizers"
69 | },
70 | {
71 | "text": "Configuration file",
72 | "url": "config"
73 | },
74 | {
75 | "text": "Command Line",
76 | "url": "command-line"
77 | },
78 | {
79 | "text": "生命周期钩子",
80 | "url": "lifecycle"
81 | },
82 | {
83 | "text": "Extension globals",
84 | "url": "globals"
85 | },
86 | {
87 | "text": "phpinfo() sections",
88 | "url": "phpinfo"
89 | },
90 | {
91 | "text": "Static analysis",
92 | "url": "static-analysis"
93 | },
94 | {
95 | "text": "优化",
96 | "url": "optimizations"
97 | },
98 | {
99 | "text": "Compiler warnings",
100 | "url": "warnings"
101 | },
102 | {
103 | "text": "License",
104 | "url": "license"
105 | }
106 | ]
107 |
--------------------------------------------------------------------------------
/zh-cn/static-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 静态分析
8 |
9 | Zephir 的编译器提供对已编译代码的静态分析。 此功能背后的想法是在运行时之前帮助开发人员发现潜在的问题, 避免意外的行为 。
10 |
11 |
12 |
13 | ## 条件未分配的变量
14 |
15 | 工作分配的静态分析尝试确定变量在赋值之前是否已使用:
16 |
17 | ```zephir
18 | class Utils
19 | {
20 | public function someMethod(b)
21 | {
22 | string a; char c;
23 |
24 | if b == 10 {
25 | let a = "hello";
26 | }
27 |
28 | //a could be unitialized here
29 | for c in a {
30 | echo c, PHP_EOL;
31 | }
32 | }
33 | }
34 | ```
35 |
36 | 上面的示例说明了一种常见情况。 只有当 `b` 等于 10时, 才会分配变量 `a`, 然后需要使用此变量的值--但它可能未初始化。 Zephir 检测到这一点, 自动将变量初始化为空字符串, 并生成警告开发人员:
37 |
38 | ```bash
39 | 警告:第一次在条件分支中分配变量a,
40 | 考虑在声明中初始化它
41 |
42 | /home/scott/test/test/utils.zep on 21 [conditional-initialization]
43 |
44 | for c in a {
45 | ```
46 |
47 | 发现这样的错误有时是很棘手的, 但是静态分析可以帮助程序员提前发现错误。
48 |
49 |
50 |
51 | ## 死码消除
52 |
53 | Zephir 通知开发人员代码中无法访问的分支, 并执行死代码消除, 这意味着它将从生成的二进制文件中删除所有代码, 因为它无论如何都无法执行:
54 |
55 | ```zephir
56 | class Utils
57 | {
58 | public function someMethod(b)
59 | {
60 | if false {
61 | // This is never executed
62 | echo "hello";
63 | }
64 | }
65 | }
66 | ```
--------------------------------------------------------------------------------
/zh-cn/warnings.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 编译警告
8 |
9 | 当发现代码可以改进或避免潜在错误的情况时,编译器会发出警告。
10 |
11 | 警告可以通过命令行参数启用,也可以添加到`config.json`以更永久地启用或禁用它们。
12 |
13 | 可以通过将警告的名称以`-w`为前缀传递来启用警告:
14 |
15 | ```bash
16 | zephir -wunused-variable -wnonexistent-function
17 | ```
18 |
19 | 警告可以通过传递前缀为`-W`的名称来禁用:
20 |
21 | ```bash
22 | zephir -Wunused-variable -Wnonexistent-function
23 | ```
24 |
25 | 支持以下警告:
26 |
27 |
28 |
29 | ## unused-variable
30 |
31 | 在声明变量但在方法中未使用时引发。 此警告默认启用。
32 |
33 | ```zephir
34 | public function some()
35 | {
36 | var e; // declared but not used
37 |
38 | return false;
39 | }
40 | ```
41 |
42 |
43 |
44 | ## unused-variable-external
45 |
46 | 当一个参数被声明但在方法中没有使用时引发。
47 |
48 | ```zephir
49 | public function sum(a, b, c) // c is not used
50 | {
51 | return a + b;
52 | }
53 | ```
54 |
55 |
56 |
57 | ## possible-wrong-parameter-undefined
58 |
59 | 当一个方法以错误的类型调用参数时引发:
60 |
61 | ```zephir
62 | public function some()
63 | {
64 | return this->sum("a string", "another"); // wrong parameters passed
65 | }
66 |
67 | public function sum(int a, int b)
68 | {
69 | return a + b;
70 | }
71 | ```
72 |
73 |
74 |
75 | ## nonexistent-function
76 |
77 | 调用编译时不存在的函数时引发:
78 |
79 | ```zephir
80 | public function some()
81 | {
82 | someFunction(); // someFunction does not exist
83 | }
84 | ```
85 |
86 |
87 |
88 | ## nonexistent-class
89 |
90 | 当使用编译时不存在的类时引发:
91 |
92 | ```zephir
93 | public function some()
94 | {
95 | var a;
96 |
97 | let a = new \MyClass(); // MyClass does not exist
98 | }
99 | ```
100 |
101 |
102 |
103 | ## non-valid-isset
104 |
105 | 当编译器检测到正在对非数组或-对象值执行“isset”操作时引发:
106 |
107 | ```zephir
108 | public function some()
109 | {
110 | var b = 1.2;
111 |
112 | return isset b[0]; // variable integer 'b' used as array
113 | }
114 | ```
115 |
116 |
117 |
118 | ## non-array-update
119 |
120 | 当编译器检测到正在对非数组值执行数组更新操作时引发:
121 |
122 | ```zephir
123 | public function some()
124 | {
125 | var b = 1.2;
126 | let b[0] = true; // variable 'b' cannot be used as array
127 | }
128 | ```
129 |
130 |
131 |
132 | ## non-valid-objectupdate
133 |
134 | 当编译器检测到正在对非对象值进行对象更新操作时引发:
135 |
136 | ```zephir
137 | public function some()
138 | {
139 | var b = 1.2;
140 | let b->name = true; // variable 'b' cannot be used as object
141 | }
142 | ```
143 |
144 |
145 |
146 | ## non-valid-fetch
147 |
148 | 当编译器检测到正在对非数组或-对象值进行'fetch'操作时引发:
149 |
150 | ##### 变量整数'b'用作数组
151 |
152 | ```zephir
153 | public function some()
154 | {
155 | var b = 1.2, a;
156 | fetch a, b[0];
157 | }
158 | ```
159 |
160 |
161 |
162 | ## invalid-array-index
163 |
164 | 当编译器检测到使用了无效的数组索引时引发:
165 |
166 | ```zephir
167 | public function some(var a)
168 | {
169 | var b = [];
170 | let a[b] = true;
171 | }
172 | ```
173 |
174 |
175 |
176 | ## non-array-append
177 |
178 | 当编译器检测到一个元素被附加到一个非数组变量时引发:
179 |
180 | ```zephir
181 | public function some()
182 | {
183 | var b = false;
184 | let b[] = "some value";
185 | }
186 | ```
--------------------------------------------------------------------------------
/zh-cn/welcome.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | language: 'zh-cn'
4 | version: '0.12'
5 | ---
6 |
7 | # 欢迎!
8 |
9 | Zephir,一种开源的高级语言,旨在简化PHP扩展的创建和可维护性,重点关注类型和内存安全性。
10 |
11 |
12 |
13 | ## 一些特征
14 |
15 | Zephir 的主要特点是:
16 |
17 | | 属性 | 说明 |
18 | | ---- | -------------- |
19 | | 类型系统 | 动态/静态 |
20 | | 内存安全 | 不允许使用指针或直接内存管理 |
21 | | 编译模型 | 预编译 |
22 | | 内存模型 | 任务本地垃圾回收 |
23 |
24 |
25 |
26 | ## 一个小尝试
27 |
28 | 下面的代码使用筛选变量的方法注册一个类, 返回它们的字母字符:
29 |
30 | ```zephir
31 | namespace MyLibrary;
32 |
33 | /**
34 | * Filter
35 | */
36 | class Filter
37 | {
38 | /**
39 | * 过滤一个字符串,返回它的alpha字符
40 | *
41 | * @param string str
42 | */
43 | public function alpha(string str)
44 | {
45 | char ch; string filtered = "";
46 |
47 | for ch in str {
48 | if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
49 | let filtered .= ch;
50 | }
51 | }
52 |
53 | return filtered;
54 | }
55 | }
56 | ```
57 |
58 | 该类可从 php 中使用, 如下所示:
59 |
60 | ```php
61 | alpha("01he#l.lo?/1"); // prints hello
65 | ```
66 |
67 |
68 |
69 | ## 外部链接
70 |
71 | 下面我们收集了您可能感兴趣的外部资源链接:
72 |
73 | - [类型系统](https://en.wikipedia.org/wiki/Type_system)
74 | - [内存安全](https://en.wikipedia.org/wiki/Memory_safety)
75 | - [预编译](https://en.wikipedia.org/wiki/Ahead-of-time_compilation)
76 | - [内存管理](https://en.wikipedia.org/wiki/Memory_management)
--------------------------------------------------------------------------------