Zephir is a compiled high level language aimed to the creation of C-extensions for PHP.

Overview

Zephir

Build on Linux Build on Windows Latest Stable Version MIT License

Zephir - is a high level programming language that eases the creation and maintainability of extensions for PHP. Zephir extensions are exported to C code that can be compiled and optimized by major C compilers such as gcc/clang/vc++. Functionality is exposed to the PHP language.

Documentation

Community

Contributing

Zephir is an Open Source, community-driven project. See CONTRIBUTING.md for details about contributions to this repository.

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]

Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

License

Zephir licensed under the MIT License. See the LICENSE file for more information.

Comments
  • PHP 7 create_instance_params is causing seg fault

    PHP 7 create_instance_params is causing seg fault

    So, if we define in phalcon view like this:

    use Phalcon\Mvc\View;
    
    $di = new \Phalcon\Di\FactoryDefault();
    
    $di->set('view',function(){
        $view=new \Phalcon\Mvc\View\Simple;
        $view->registerEngines([
            '.volt'=>'Phalcon\Mvc\View\Engine\Volt'
        ]);
        return $view;
    });
    

    Then we got a create_instance_params called here https://github.com/phalcon/cphalcon/blob/2.1.x/phalcon/di.zep#L235 With name 'Phalcon\Mvc\View\Engine\Volt' and arguments [di, view object]

    And it causes a seg fault. Log is here:

    http://pastebin.com/T7vmJsUD

    Also on debug version i dont have stack trace(maybe i do something wrong) and code is not working(just white page)

    Also just to clarify - zephir has problems to create instance of class when it's provided as string(as i did here). It's not phalcon related problem anyhow. From backtrace i guess he has some problems with passing arguments/bind them or something like this but i don't know.

    bug 
    opened by Jurigag 70
  • [Windows] Support x64 for parser compilation

    [Windows] Support x64 for parser compilation

    Hi there,

    I'm trying to get Zephir to work on a Windows 7 64 bits system with PHP 7 NTS (as requested) 64 bits.

    It fails. Here is what I get:

    D:\dev\PHP\Ext\test>zephir build zephir_parser extension not loaded, compiling it Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x86 Copyright (C) Microsoft Corporation. All rights reserved.

    'lemon' is not recognized as an internal or external command, operable program or batch file.

    D:\wamp\www\zephir\parser\parser>REM Build Lemon

    D:\wamp\www\zephir\parser\parser>cl lemon.c lemon.c lemon.c(1413): warning C4113: 'int (__cdecl *)()' differs in parameter lists from 'int (__cdecl *)(const void *,const void *)' cl : Command line error D8027 : cannot execute 'c2'

    D:\wamp\www\zephir\parser\parser>del parser.c parser.h scanner.c

    D:\wamp\www\zephir\parser\parser>re2c -o scanner.c scanner.re

    D:\wamp\www\zephir\parser\parser>lemon -s parser.lemon

    D:\wamp\www\zephir\parser\parser>type base.c 1>>parser.c Preparing for parser compilation... ERROR: bison is required Compiling the parser...

    Microsoft (R) Program Maintenance Utility Version 14.00.23506.0 Copyright (C) Microsoft Corporation. All rights reserved.

    NMAKE : fatal error U1064: MAKEFILE not found and no target specified Stop.

    PHP Warning: copy(Release/php_zephir_parser.dll): failed to open stream: No such file or directory in D:\wamp\www\zephir\Library\Compiler.php on line 233

    Warning: copy(Release/php_zephir_parser.dll): failed to open stream: No such file or directory in D:\wamp\www\zephir\Library\Compiler.php on line 233 Zephir\Exception: The zephir parser extension could not be found or compiled!

    I followed the instructions here: https://github.com/phalcon/zephir/blob/master/WINDOWS.md

    But it complains that it "cannot execute 'c2'", which I don't know what it means.

    Could someone please help?

    Thank you a lot!

    windows 
    opened by rkyoku 57
  • Access to undeclared static property

    Access to undeclared static property

    When ajax request more than 3 times, there will be "Access to undeclared static property" E.g

    namespace XqKeji;
    
    class Di
    {
    	private static _default;
    
    	public static function getInstance()
    	{
    		var di
    		let di = self::_default;
    
    		if !di {
    			let di = new self();
    			let self::_default = di;
    		}
    
    		return self::_default;
    	}
    }
    
    class app
    {
    	public function __construct()
    	{
    		var di;
    		let di = \XqKeji\Di::getInstance();
    	}
    }
    

    Test:

    <?php
    $App = new App();
    
    

    in window php7.0 ts

    bug 
    opened by xqkeji 55
  • fix for php7.1

    fix for php7.1

    this is fix to issue #1389 and incompatible method returnString for zendEngine3

    I tested the rebuild phalcon 3.1.x it works well for now

    php.7.1.1 and php.7.2.0-dev zephir 0.9.6a-dev-72dbb2063e

    opened by rafmichalak84 45
  • Use phalcon from zephir module

    Use phalcon from zephir module

    As the title states how can i use phalcon from within my own zephir module

    namespace Rapid\Models;
    class Users extends \Phalcon\Mvc\Model
    {
    }
    

    Thanks Dave

    discussion 
    opened by DaveM2011 42
  • PHP7

    PHP7

    It seems the generation of extensions from PHP5 changes dramatically in PHP7 due to the modifications to internal structures.

    As I see it will require:

    • A separate kernel specifically focused on PHP7
    • A new memory manager designed to address the reference counting changes in PHP7
    • A new approach on generating method/function calls
    • A new approach on reusing zval variables
    • It would be hard to have a common generated code for both PHP5 and PHP7

    Also, It seems that the amount of changes is larger than I expected previously and I think these changes will take many hours and it's something we have to address as soon as possible before move forward.

    opened by andresgutierrez 41
  • Performance degradation

    Performance degradation

    Im not telling that fixed issues are bad or something, but those method call time difference in microbench.php is pretty big:

    Benchmark Zephir 0.9.6a-dev
    empty for in range 0.048
    $x = $this->x      0.262
    $this->x = 0       0.261
    self::a = 0        0.130
    $this->x++         0.532
    $this->x--         0.541
    isset($this->x)    0.115
    isset(self::A)     0.048
    empty($this->x)    0.298
    empty(self::a)     0.256
    $this->f()         0.260
    self::f()          0.266
    self::f() -> true  0.262
    $x = Foo::TEST     0.051
    ------------------------
    Total              3.332
    
    Benchmark Zephir 0.9.7
    empty for in range 0.046
    $x = $this->x      0.273
    $this->x = 0       0.271
    self::a = 0        0.230
    $this->x++         0.537
    $this->x--         0.547
    isset($this->x)    0.113
    isset(self::A)     0.046
    empty($this->x)    0.307
    empty(self::a)     0.249
    $this->f()         1.534
    self::f()          1.825
    self::f() -> true  1.852
    $x = Foo::TEST     0.052
    ------------------------
    Total              7.883
    

    Are there any plans to improve current one speed if it's anyhow possible?

    Keep in mind that this is only about method calling itself, like how it's called(am i right?). Method in microbench is called 5000000, in real app on phalcon i guess there is less than 5000 calls.

    opened by Jurigag 39
  • Rethinking Zephir

    Rethinking Zephir

    After several months working on Zephir, we are very happy with the progress so far, in a few months we will reach a beta version and then we'll enjoy all its potential. We have reached over 1000 commits and counting and there's a lot to do. This project has allowed us to do a little more CS research and it has been very interesting for us.

    Moreover, we must admit that we're not sure what will happen with PHP in the future, despite this, we are creating a tool which allows to take advantage of one the less exploited PHP features by the community at large (C extensions) and for a long time it has been reserved to experienced C programmers or advanced users.

    Also in Zephir, we have found the opportunity to implement features that we have always dreamed of PHP but for one or another reason they are not a reality today:

    We believe they will help us to build a better framework and it can help you to build your own tools in a new interesting way. Not everyone needs these features and not all may agree with them. However, we hope that one day these features will considered in the official PHP so we all can enjoy them. No matter what happens, we are sure that PHP will continue evolving regardless of the path taken.

    Zephir was initially conceived as a high-level language that abstracts low-level details and allows you to compile your code. Currently based on a high-level representation it generates C code that can be compiled by leading compilers such as gcc/clang/vc with all the advantages that this brings to the table.

    Nevertheless, we know that Zephir, being a high-level language, it could also function as a meta-language rather than just a DSL (domain specific language).

    After thinking a bit on this I'm creating this thread to discuss an idea with you guys.

    If we could restructure Zephir so that it can generate code in both PHP and C, this could make Zephir a much more powerful tool than ever before.

    Generating C:

    • The code can be compiled, improving performance and reducing resource consumption
    • Some important level of code protection
    • Code is exported as a C-extension (shared library or Windows DLL)
    zephir generate c
    

    Generating PHP:

    • PHP code can run everywhere where the language is available (shared hostings, servers with restrictions, other PHP implementations, etc)
    • Code is exported as a PHP library (phar, standard PHP library installable via composer, etc)
    zephir generate php
    

    Using C-extensions:

    • Production environments, when more performance is required and install c-extensions is feasible

    Using PHP libraries:

    • Development/Testing environments, other restricted environments, other PHP implementations, etc.

    Possible cons:

    • C code blocks cannot be exported to PHP
    • Integrations with low level C libraries couldn't be exported to PHP
    • Introduce incompatibilities due to the different runtimes (can be solved with enough tests)

    With regard to this we can:

    a) Implement this now b) Release Zephir 1.0 (aka stable) and implement this after that c) Do not implement it at all

    Looking forward to your comments,

    discussion 
    opened by phalcon 37
  • Support for php8

    Support for php8

    Add php 8.0 support. We have feature freeze and beta1 now https://wiki.php.net/todo/php80.

    It's disabled in composer/build. Can we enable (with allowed failures) and see what's failing?

    Would be good if it's ready on Nov 26 2020 (GA).

    nfr 
    opened by mruz 36
  • Invalid type argument of unary '*' (have 'zval')

    Invalid type argument of unary '*' (have 'zval')

    On the PHP7:

    protected function stripPadding(string value) -> string
        {
            var pad, len;
    
            let len = (int) strlen(value),
                pad = (int) ord(value[len - 1]);
    
            return this->paddingIsValid(pad, value) ? substr(value, 0, len - pad) : value;
        }
    
    PHP_METHOD(Ice_Crypt, stripPadding) {
    
            unsigned char _0;
            int pad = 0, len = 0, ZEPHIR_LAST_CALL_STATUS;
            zval *value_param = NULL, _1, _2, _3, _4, _5;
            zval value;
            zval this_zv;
            zval *this_ptr = getThis();
            if (EXPECTED(this_ptr)) {
                    ZVAL_OBJ(&this_zv, Z_OBJ_P(this_ptr));
                    this_ptr = &this_zv;
            } else this_ptr = NULL;
    
            ZVAL_UNDEF(&value);
            ZVAL_UNDEF(&_1);
            ZVAL_UNDEF(&_2);
            ZVAL_UNDEF(&_3);
            ZVAL_UNDEF(&_4);
            ZVAL_UNDEF(&_5);
    
            ZEPHIR_MM_GROW();
            zephir_fetch_params(1, 1, 0, &value_param);
    
            zephir_get_strval(&value, value_param);
    
    
            len = zephir_fast_strlen_ev(&value);
            _0 = ZEPHIR_STRING_OFFSET(value, (len - 1));
            ZVAL_LONG(&_1, _0);
            ZEPHIR_CALL_FUNCTION(&_2, "ord", NULL, 69, &_1);
            zephir_check_call_status();
            pad = zephir_get_intval(&_2);
            ZEPHIR_INIT_VAR(&_3);
            ZVAL_LONG(&_1, pad);
            ZEPHIR_CALL_METHOD(&_4, this_ptr, "paddingisvalid", NULL, 0, &_1, &value);
            zephir_check_call_status();
            if (zephir_is_true(&_4)) {
                    ZVAL_LONG(&_1, 0);
                    ZVAL_LONG(&_5, (len - pad));
                    zephir_substr(&_3, &value, 0 , zephir_get_intval(&_5), 0);
            } else {
                    ZEPHIR_CPY_WRT(&_3, &value);
            }
            RETURN_CCTOR(_3);
    
    }
    
    In file included from /usr/include/php7/Zend/zend.h:35:0,
                     from /usr/include/php7/main/php.h:35,
                     from /home/mruz/framework/ext/ice/crypt.zep.c:6:
    /home/mruz/framework/ext/ice/crypt.zep.c: In function 'zim_Ice_Crypt_stripPadding':
    /usr/include/php7/Zend/zend_types.h:519:39: error: invalid type argument of unary '*' (have 'zval')
     #define Z_STRLEN_P(zval_p)   Z_STRLEN(*(zval_p))
                                           ^
    /usr/include/php7/Zend/zend_string.h:41:26: note: in definition of macro 'ZSTR_LEN'
     #define ZSTR_LEN(zstr)  (zstr)->len
                              ^
    /usr/include/php7/Zend/zend_types.h:518:36: note: in expansion of macro 'Z_STR'
     #define Z_STRLEN(zval)    ZSTR_LEN(Z_STR(zval))
                                        ^
    /usr/include/php7/Zend/zend_types.h:519:30: note: in expansion of macro 'Z_STRLEN'
     #define Z_STRLEN_P(zval_p)   Z_STRLEN(*(zval_p))
                                  ^
    ./kernel/operators.h:74:66: note: in expansion of macro 'Z_STRLEN_P'
     #define ZEPHIR_STRING_OFFSET(op1, index) ((index >= 0 && index < Z_STRLEN_P(op1)) ? Z_STRVAL_P(op1)[index] : '\0')
                                                                      ^
    /home/mruz/framework/ext/ice/crypt.zep.c:499:7: note: in expansion of macro 'ZEPHIR_STRING_OFFSET'
      _0 = ZEPHIR_STRING_OFFSET(value, (len - 1));
           ^
    /usr/include/php7/Zend/zend_types.h:516:39: error: invalid type argument of unary '*' (have 'zval')
     #define Z_STRVAL_P(zval_p)   Z_STRVAL(*(zval_p))
                                           ^
    /usr/include/php7/Zend/zend_string.h:40:26: note: in definition of macro 'ZSTR_VAL'
     #define ZSTR_VAL(zstr)  (zstr)->val
                              ^
    /usr/include/php7/Zend/zend_types.h:515:36: note: in expansion of macro 'Z_STR'
     #define Z_STRVAL(zval)    ZSTR_VAL(Z_STR(zval))
                                        ^
    /usr/include/php7/Zend/zend_types.h:516:30: note: in expansion of macro 'Z_STRVAL'
     #define Z_STRVAL_P(zval_p)   Z_STRVAL(*(zval_p))
                                  ^
    ./kernel/operators.h:74:85: note: in expansion of macro 'Z_STRVAL_P'
     #define ZEPHIR_STRING_OFFSET(op1, index) ((index >= 0 && index < Z_STRLEN_P(op1)) ? Z_STRVAL_P(op1)[index] : '\0')
                                                                                         ^
    /home/mruz/framework/ext/ice/crypt.zep.c:499:7: note: in expansion of macro 'ZEPHIR_STRING_OFFSET'
      _0 = ZEPHIR_STRING_OFFSET(value, (len - 1));
           ^
    make: *** [ice/crypt.lo] Błąd 1
    make: *** Oczekiwanie na niezakończone zadania....
    
    bug 
    opened by mruz 25
  • Initial support for PHP7

    Initial support for PHP7

    This PR provides only an "intermediate refactoring" of the current source code, which is not the abstract state zephir would need to support PHP code generation, with total separation of backends.

    This PR does only aim to provide PHP7 compatibility and therefor required some refactoring, which was done in a limited extent.

    Stuff which would have to be done for that:

    • Move the operator/statement/optimizer logic that's depending on the backend to classes of the backend (which currently partly is just in-place in the old files with conditionals)
      So you would have a class providing the general implementation, which is shared between backends (common code for validating parameters, checking input, ...)
      and a version per backend which handles code generation (and temp variable usage, ...)

    This PR

    • provides initial support for PHP7 (ZE3) Extensions (compiler and kernel support)
      (testcases pass, except preg-match, requires proper reference support in zephir)

    Todos

    • [x] compare generated sources for ZE2
      • generated code for zephir tests seems to match
    • [x] complete some backend definitions (in BaseBackend)
    • [ ] general cleanup, eventually more performance tweaks/documentation
    opened by steffengy 25
  • error when compiling on php 8.2.0

    error when compiling on php 8.2.0

    When compiling on php 8.2.0 I get the following error:

    /home/works/dichvucoder/ext/kernel/main.c:571:34: error: too many arguments to function call, expected 0, have 1 if (zend_forbid_dynamic_call("func_get_arg()") == FAILURE)

    And

    /home/works/dichvucoder/ext/kernel/fcall.c:699:58: error: too few arguments to function call, expected 3, have 2 new_op_array = zend_compile_string(Z_STR_P(str), context);

    I tried compiling again on php 7.4.33 and 8.1.6 it still works it seems these 2 errors only appear on php 8.2.0 How to fix it?

    opened by Dichvucoder 0
  • Invalid default value

    Invalid default value

    PHP 8.1 Invalid default value

    for example:

    class Test{ public function t1(int i=0) { } }

    var t; let t=new Test(); t->t1();

    Since the call does not take a parameter, it usually passes a null value, so the default value of the parameter cannot be used.

    The default value can only be used if the type is changed to var i=0.

    opened by xqkeji 0
  • [ERROR] Unknown type: add

    [ERROR] Unknown type: add

    image

    compile-errors.log make: *** No targets specified and no makefile found. Stop. make: *** No targets specified and no makefile found. Stop.

    jdf.zep

    namespace Jdate;
    class Jdf 
    {
    public function jdate( var format,  var timestamp = "",  var none = "",  var time_zone = "Asia/Tehran",  var tr_nums = "fa") {
        var T_sec, ts, date, j_y, j_m, j_d, doy, kab, sl, out, i, sub, jdw, dny, key, avs, num, aks;
    
      let T_sec =  0;
    
      if (time_zone != "local")
      {
      date_default_timezone_set((time_zone === "") ? "Asia/Tehran" : time_zone);
      }
      let ts =  T_sec + ((timestamp === "") ? time() : this->tr_num(timestamp));
      let date =  explode("_", date("H_i_j_n_O_P_s_w_Y", ts));
      var tmpArrlh2o = this->gregorian_to_jalali(date[8], date[3], date[2]);
      let j_y = array_shift(tmpArrlh2o);
      let j_m = array_shift(tmpArrlh2o);
      let j_d = array_shift(tmpArrlh2o);
      let doy =  (j_m < 7) ? ((j_m - 1) * 31) + j_d - 1 : ((j_m - 7) * 30) + j_d + 185;
      let kab =  ((((j_y + 12) % 33) % 4) == 1) ? 1 : 0;
      let sl =  strlen(format);
      let out =  "";
      let i =  0;
      while (i < sl) {
        let sub =  substr(format, i, 1);
        if (sub == "\\") {
          var kos=i+1;
          let out .=  substr(format, kos, 1);
          continue;
        }
        switch (sub) {
    
          case "E":
          case "R":
          case "x":
          case "X":
            let out .=  "http://jdf.scr.ir";
            break;
    
          case "B":
          case "e":
          case "g":
          case "G":
          case "h":
          case "I":
          case "T":
          case "u":
          case "Z":
            let out .=  date(sub, ts);
            break;
    
          case "a":
            let out .=  (date[0] < 12) ? "ق.ظ" : "ب.ظ";
            break;
    
          case "A":
            let out .=  (date[0] < 12) ? "قبل از ظهر" : "بعد از ظهر";
            break;
    
          case "b":
            let out .=  (int) (j_m / 3.1) + 1;
            break;
    
          case "c":
            let out .=  j_y . "/" . j_m . "/" . j_d . " ،" . date[0] . ":" . date[1] . ":" . date[6] . " " . date[5];
            break;
    
          case "C":
            let out .=  (int) ((j_y + 99) / 100);
            break;
    
          case "d":
            let out .=  (j_d < 10) ? "0" . j_d : j_d;
            break;
    
          case "D":
            let out .=  jdate_words(["kh" : date[7]], " ");
            break;
    
          case "f":
            let out .=  jdate_words(["ff" : j_m], " ");
            break;
    
          case "F":
            let out .=  jdate_words(["mm" : j_m], " ");
            break;
    
          case "H":
            let out .=  date[0];
            break;
    
          case "i":
            let out .=  date[1];
            break;
    
          case "j":
            let out .=  j_d;
            break;
    
          case "J":
            let out .=  jdate_words(["rr" : j_d], " ");
            break;
    
          case "k":
            let out .=  this->tr_num(100 - (int) (doy / (kab + 365.24) * 1000) / 10, tr_nums);
            break;
    
          case "K":
            let out .=  this->tr_num((int) (doy / (kab + 365.24) * 1000) / 10, tr_nums);
            break;
    
          case "l":
            let out .=  jdate_words(["rh" : date[7]], " ");
            break;
    
          case "L":
            let out .=  kab;
            break;
    
          case "m":
            let out .=  (j_m > 9) ? j_m : "0" . j_m;
            break;
    
          case "M":
            let out .=  jdate_words(["km" : j_m], " ");
            break;
    
          case "n":
            let out .=  j_m;
            break;
    
          case "N":
            let out .=  date[7] + 1;
            break;
    
          case "o":
            let jdw =  (date[7] == 6) ? 0 : date[7] + 1;
            let dny =  364 + kab - doy;
            let out .=  (jdw > (doy + 3) && doy < 3) ? j_y - 1 : (((3 - dny) > jdw && dny < 3) ? j_y + 1 : j_y);
            break;
    
          case "O":
            let out .=  date[4];
            break;
    
          case "p":
            let out .=  jdate_words(["mb" : j_m], " ");
            break;
    
          case "P":
            let out .=  date[5];
            break;
    
          case "q":
            let out .=  jdate_words(["sh" : j_y], " ");
            break;
    
          case "Q":
            let out .=  kab + 364 - doy;
            break;
    
          case "r":
            let key =  jdate_words(["rh" : date[7], "mm" : j_m]);
            let out .=  date[0] . ":" . date[1] . ":" . date[6] . " " . date[4] . " " . key["rh"] . "، " . j_d . " " . key["mm"] . " " . j_y;
            break;
    
          case "s":
            let out .=  date[6];
            break;
    
          case "S":
            let out .=  "ام";
            break;
    
          case "t":
            let out .=  (j_m != 12) ? (31 - (int) (j_m / 6.5)) : (kab + 29);
            break;
    
          case "U":
            let out .=  ts;
            break;
    
          case "v":
            let out .=  jdate_words(["ss" : (j_y % 100)], " ");
            break;
    
          case "V":
            let out .=  jdate_words(["ss" : j_y], " ");
            break;
    
          case "w":
            let out .=  (date[7] == 6) ? 0 : date[7] + 1;
            break;
    
          case "W":
            let avs =  ((date[7] == 6) ? 0 : date[7] + 1) - (doy % 7);
            if ($avs < 0)
            {
            let avs +=  7;
            }
           let num =  (int) ((doy + avs) / 7);
            if (avs < 4) {
              let num++;
            } elseif (num < 1) {
              let num =  (avs == 4 || avs == (((((j_y % 33) % 4) - 2) == ((int) ((j_y % 33) * 0.05))) ? 5 : 4)) ? 53 : 52;
            }
            let aks =  avs + kab;
            let aks =  0;
    
            if (aks == 7) {
            let aks =0;
            }
             let out .=  ((kab + 363 - doy) < aks && aks < 3) ? "01" : ((num < 10) ? "0" . num : num);
            break;
    
          case "y":
            let out .=  substr(j_y, 2, 2);
            break;
    
          case "Y":
            let out .=  j_y;
            break;
    
          case "z":
            let out .=  doy;
            break;
    
          default:
            let out .=  sub;
        }
         let i=i+1;
      }
      return (tr_nums != "en") ? this->tr_num(out, "fa", ".") : out;
    }
    
    
    public function jstrftime( var format,  var timestamp = "",  var none = "",  var time_zone = "Asia/Tehran",  var tr_nums = "fa") {
        var T_sec, ts, date, j_y, j_m, j_d, doy, kab, sl, out, i, sub, avs, num, aks, tmp, jdw, dny, key;
    
      let T_sec =  0;
    
      if (time_zone != "local")
      {
      date_default_timezone_set((time_zone === "") ? "Asia/Tehran" : time_zone);
      }
      let ts =  T_sec + ((timestamp === "") ? time() : this->tr_num(timestamp));
      let date =  explode("_", date("h_H_i_j_n_s_w_Y", ts));
      var tmpArri5xs = this->gregorian_to_jalali(date[7], date[4], date[3]);
      let j_y = array_shift(tmpArri5xs);
      let j_m = array_shift(tmpArri5xs);
      let j_d = array_shift(tmpArri5xs);
      let doy =  (j_m < 7) ? ((j_m - 1) * 31) + j_d - 1 : ((j_m - 7) * 30) + j_d + 185;
      let kab =  ((((j_y + 12) % 33) % 4) == 1) ? 1 : 0;
      let sl =  strlen(format);
      let out =  "";
      let i =  0;
      while (i < sl) {
        let sub =  substr(format, i, 1);
        if (sub == "%") {
          let kos=i+1;
          let sub =  substr(format, kos, 1);
        } else {
          let out .=  sub;
          continue;
        }
        switch (sub) {
    
    
          case "a":
            let out .=  jdate_words(["kh" : date[6]], " ");
            break;
    
          case "A":
            let out .=  jdate_words(["rh" : date[6]], " ");
            break;
    
          case "d":
            let out .=  (j_d < 10) ? "0" . j_d : j_d;
            break;
    
          case "e":
            let out .=  (j_d < 10) ? " " . j_d : j_d;
            break;
    
          case "j":
            let out .=  str_pad(doy + 1, 3, 0, STR_PAD_LEFT);
            break;
    
          case "u":
            let out .=  date[6] + 1;
            break;
    
          case "w":
            let out .=  (date[6] == 6) ? 0 : date[6] + 1;
            break;
    
    
          case "U":
            let avs =  ((date[6] < 5) ? date[6] + 2 : date[6] - 5) - (doy % 7);
    
    
            if (avs < 0) {
            let avs +=7;
            }
             let num =  (int) ((doy + avs) / 7) + 1;
            if (avs > 3 || avs == 1) {
            let num-=1;
            }
            let out .=  (num < 10) ? "0" . num : num;
            break;
    
          case "V":
            let avs =  ((date[6] == 6) ? 0 : date[6] + 1) - (doy % 7);
    
    
            if (avs < 0) {
             let avs +=  7;
            }
            let num =  (int)((doy + avs) / 7);
            if (avs < 4) {
             let num+=1;
            } elseif (num < 1) {
              let num =  (avs == 4 || avs == (((((j_y % 33) % 4) - 2) == ((int) ((j_y % 33) * 0.05))) ? 5 : 4)) ? 53 : 52;
            }
            let aks =  avs + kab;
    
    
            if (aks == 7) {   let aks =  0;}
                   let out .=  ((kab + 363 - doy) < aks && aks < 3) ? "01" : ((num < 10) ? "0" . num : num);
            break;
    
          case "W":
            let avs =  ((date[6] == 6) ? 0 : date[6] + 1) - (doy % 7);
    
    
            if (avs < 0) {
            let avs +=  7;
            }
             let num =  (int) ((doy + avs) / 7) + 1;
            if (avs > 3){
           let  num-=1;
            }
            let out .=  (num < 10) ? "0" . num : num;
            break;
    
    
          case "b":
          case "h":
            let out .=  jdate_words(["km" : j_m], " ");
            break;
    
          case "B":
            let out .=  jdate_words(["mm" : j_m], " ");
            break;
    
          case "m":
            let out .=  (j_m > 9) ? j_m : "0" . j_m;
            break;
    
    
          case "C":
            let tmp =  (int) (j_y / 100);
            let out .=  (tmp > 9) ? tmp : "0" . tmp;
            break;
    
          case "g":
            let jdw =  (date[6] == 6) ? 0 : date[6] + 1;
            let dny =  364 + kab - doy;
            let out .=  substr((jdw > (doy + 3) && doy < 3) ? j_y - 1 : (((3 - dny) > jdw && dny < 3) ? j_y + 1 : j_y), 2, 2);
            break;
    
          case "G":
            let jdw =  (date[6] == 6) ? 0 : date[6] + 1;
            let dny =  364 + kab - doy;
            let out .=  (jdw > (doy + 3) && doy < 3) ? j_y - 1 : (((3 - dny) > jdw && dny < 3) ? j_y + 1 : j_y);
            break;
    
          case "y":
            let out .=  substr(j_y, 2, 2);
            break;
    
          case "Y":
            let out .=  j_y;
            break;
    
    
          case "H":
            let out .=  date[1];
            break;
    
          case "I":
            let out .=  date[0];
            break;
    
          case "l":
            let out .=  (date[0] > 9) ? date[0] : " " . (int) date[0];
            break;
    
          case "M":
            let out .=  date[2];
            break;
    
          case "p":
            let out .=  (date[1] < 12) ? "قبل از ظهر" : "بعد از ظهر";
            break;
    
          case "P":
            let out .=  (date[1] < 12) ? "ق.ظ" : "ب.ظ";
            break;
    
          case "r":
            let out .=  date[0] . ":" . date[2] . ":" . date[5] . " " . ((date[1] < 12) ? "قبل از ظهر" : "بعد از ظهر");
            break;
    
          case "R":
            let out .=  date[1] . ":" . date[2];
            break;
    
          case "S":
            let out .=  date[5];
            break;
    
          case "T":
            let out .=  date[1] . ":" . date[2] . ":" . date[5];
            break;
    
          case "X":
            let out .=  date[0] . ":" . date[2] . ":" . date[5];
            break;
    
          case "z":
            let out .=  date("O", ts);
            break;
    
          case "Z":
            let out .=  date("T", ts);
            break;
    
    
          case "c":
            let key =  jdate_words(["rh" : date[6], "mm" : j_m]);
            let out .=  date[1] . ":" . date[2] . ":" . date[5] . " " . date("P", ts) . " " . key["rh"] . "، " . j_d . " " . key["mm"] . " " . j_y;
            break;
    
          case "D":
            let out .=  substr(j_y, 2, 2) . "/" . ((j_m > 9) ? j_m : "0" . j_m) . "/" . ((j_d < 10) ? "0" . j_d : j_d);
            break;
    
          case "F":
            let out .=  j_y . "-" . ((j_m > 9) ? j_m : "0" . j_m) . "-" . ((j_d < 10) ? "0" . j_d : j_d);
            break;
    
          case "s":
            let out .=  ts;
    
            break;
    
          case "x":
            let out .=  substr(j_y, 2, 2) . "/" . ((j_m > 9) ? j_m : "0" . j_m) . "/" . ((j_d < 10) ? "0" . j_d : j_d);
            break;
    
    
          case "n":
            let out .=  "\n";
            break;
    
          case "t":
            let out .=  "\t";
            break;
    
          case "%":
            let out .=  "%";
            break;
    
          default:
            let out .=  sub;
        }
        let  i+=1;
      }
      return (tr_nums != "en") ? this->tr_num(out, "fa", ".") : out;
    }
    
    
    public function jmktime( var h = "",  var m = "",  var s = "",  var jm = "",  var jd = "",  var jy = "",  var none = "",  var timezone = "Asia/Tehran") {
        var jdate, gy, gm, gd;
      if (timezone != "local") {date_default_timezone_set(timezone);}
      if (h === "") {
        return time();
      } else {
        var tmpArrrf63 = explode("_", this->tr_num(h . "_" . m . "_" . s . "_" . jm . "_" . jd . "_" . jy));
        let h = array_shift(tmpArrrf63);
        let m = array_shift(tmpArrrf63);
        let s = array_shift(tmpArrrf63);
        let jm = array_shift(tmpArrrf63);
        let jd = array_shift(tmpArrrf63);
        let jy = array_shift(tmpArrrf63);
        if (m === "") {
          return mktime(h);
        } else {
          if (s === "") {
            return mktime(h, m);
          } else {
            if (jm === "") {
              return mktime(h, m, s);
            } else {
              let jdate =  explode("_", jdate("Y_j", "", "", timezone, "en"));
              if (jd === "") {
                var tmpArrfog2 = jalali_to_gregorian(jdate[0], jm, jdate[1]);
                let gy = array_shift(tmpArrfog2);
                let gm = array_shift(tmpArrfog2);
                let gd = array_shift(tmpArrfog2);
                return mktime(h, m, s, gm);
              } else {
                if (jy === "") {
                  var tmpArr16mx = jalali_to_gregorian(jdate[0], jm, jd);
                  let gy = array_shift(tmpArr16mx);
                  let gm = array_shift(tmpArr16mx);
                  let gd = array_shift(tmpArr16mx);
                  return mktime(h, m, s, gm, gd);
                } else {
                  var tmpArrwtl6 = jalali_to_gregorian(jy, jm, jd);
                  let gy = array_shift(tmpArrwtl6);
                  let gm = array_shift(tmpArrwtl6);
                  let gd = array_shift(tmpArrwtl6);
                  return mktime(h, m, s, gm, gd, gy);
                }
              }
            }
          }
        }
      }
    }
    
    
    public function jgetdate( var timestamp = "",  var none = "",  var timezone = "Asia/Tehran",  var tn = "en") {
        var ts, jdate;
      let ts =  (timestamp === "") ? time() : this->tr_num(timestamp);
      let jdate =  explode("_", jdate("F_G_i_j_l_n_s_w_Y_z", ts, "", timezone, tn));
      return [
        "seconds" : this->tr_num((int) this->tr_num(jdate[6]), tn),
        "minutes" : this->tr_num((int) this->tr_num(jdate[2]), tn),
        "hours" : jdate[1],
        "mday" : jdate[3],
        "wday" : jdate[7],
        "mon" : jdate[5],
        "year" : jdate[8],
        "yday" : jdate[9],
        "weekday" : jdate[4],
        "month" : jdate[0],
        0 : this->tr_num(ts, tn)
      ];
    }
    
    
    public function jcheckdate( var jm,  var jd,  var jy) {
        var l_d;
      var tmpArr6fpz = explode("_", this->tr_num(jm . "_" . jd . "_" . jy));
      let jm = array_shift(tmpArr6fpz);
      let jd = array_shift(tmpArr6fpz);
      let jy = array_shift(tmpArr6fpz);
      let l_d =  (jm == 12 && (((jy + 12) % 33) % 4) != 1) ? 29 : (31 - (int) (jm / 6.5));
      return (jm > 12 || jd > l_d || jm < 1 || jd < 1 || jy < 1) ? false : true;
    }
    
    
    public  function tr_num( var str,  var mod = "en",  var mf = "٫") {
        var num_a, key_a;
      let num_a =  ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."];
      let key_a =  ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹", mf];
      return (mod == "fa") ? str_replace(num_a, key_a, str) : str_replace(key_a, num_a, str);
    }
    
    
    public function jdate_words( var x_array,  var mod = "") {
        var x_type, num, sl, xy3, h3, h34, h4, p34, k34, xy4, k3, k4, key;
      for x_type,num in x_array {
        let num =  (int) this->tr_num(num);
        switch (x_type) {
    
          case "ss":
            let sl =  strlen(num);
            let xy3 =  substr(num, 2 - sl, 1);
            let h3 ="";
              let h34 = "";
               let h4 =  "";
            if (xy3 == 1) {
              let p34 =  "";
              let k34 =  ["ده", "یازده", "دوازده", "سیزده", "چهارده", "پانزده", "شانزده", "هفده", "هجده", "نوزده"];
              let h34 =  k34[substr(num, 2 - sl, 2) - 10];
            } else {
              let xy4 =  substr(num, 3 - sl, 1);
              let p34 =  (xy3 == 0 || xy4 == 0) ? "" : " و ";
              let k3 =  ["", "", "بیست", "سی", "چهل", "پنجاه", "شصت", "هفتاد", "هشتاد", "نود"];
              let h3 =  k3[xy3];
              let k4 =  ["", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه"];
              let h4 =  k4[xy4];
            }
            let x_array[x_type] =  ((num > 99) ? str_replace(
              ["12", "13", "14", "19", "20"],
              ["هزار و دویست", "هزار و سیصد", "هزار و چهارصد", "هزار و نهصد", "دوهزار"],
              substr(num, 0, 2)
            ) . ((substr(num, 2, 2) == "00") ? "" : " و ") : "") . h3 . p34 . h34 . h4;
            break;
    
          case "mm":
            let key =  ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند"];
            let x_array[x_type] =  key[num - 1];
            break;
    
          case "rr":
            let key =  [
              "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه", "ده", "یازده", "دوازده", "سیزده", "چهارده", "پانزده", "شانزده", "هفده", "هجده", "نوزده", "بیست", "بیست و یک", "بیست و دو", "بیست و سه", "بیست و چهار", "بیست و پنج", "بیست و شش", "بیست و هفت", "بیست و هشت", "بیست و نه", "سی", "سی و یک"
            ];
            let x_array[x_type] =  key[num - 1];
            break;
    
          case "rh":
            let key =  ["یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه"];
            let x_array[x_type] =  key[num];
            break;
    
          case "sh":
            let key =  ["مار", "اسب", "گوسفند", "میمون", "مرغ", "سگ", "خوک", "موش", "گاو", "پلنگ", "خرگوش", "نهنگ"];
            let x_array[x_type] =  key[num % 12];
            break;
    
          case "mb":
            let key =  ["حمل", "ثور", "جوزا", "سرطان", "اسد", "سنبله", "میزان", "عقرب", "قوس", "جدی", "دلو", "حوت"];
            let x_array[x_type] =  key[num - 1];
            break;
    
          case "ff":
            let key =  ["بهار", "تابستان", "پاییز", "زمستان"];
            let x_array[x_type] =  key[(int) (num / 3.1)];
            break;
    
          case "km":
            let key =  ["فر", "ار", "خر", "تی‍", "مر", "شه‍", "مه‍", "آب‍", "آذ", "دی", "به‍", "اس‍"];
            let x_array[x_type] =  key[num - 1];
            break;
    
          case "kh":
            let key =  ["ی", "د", "س", "چ", "پ", "ج", "ش"];
            let x_array[x_type] =  key[num];
            break;
    
          default:
            let x_array[x_type] =  num;
        }
      }
      return (mod === "") ? x_array : implode(mod, x_array);
    }
    
    
    public  function gregorian_to_jalali( var gy,  var gm,  var gd,  var mod = "") {
        var g_d_m, gy2, days, jy, jm, jd;
       var tmpArrcxet = explode("_", this->tr_num(gy . "_" . gm . "_" . gd));
       let gy = array_shift(tmpArrcxet);
       let gm = array_shift(tmpArrcxet);
       let gd = array_shift(tmpArrcxet);
      let g_d_m =  [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
      let gy2 =  (gm > 2) ? (gy + 1) : gy;
      let days =  355666 + (365 * gy) + ((int) ((gy2 + 3) / 4)) - ((int) ((gy2 + 99) / 100)) + ((int) ((gy2 + 399) / 400)) + gd + g_d_m[gm - 1];
      let jy =  -1595 + (33 * ((int) (days / 12053)));
      let days %=  12053;
      let jy +=  4 * ((int) (days / 1461));
      let days %=  1461;
      if (days > 365) {
        let jy +=  (int) ((days - 1) / 365);
        let days =  (days - 1) % 365;
      }
      if (days < 186) {
        let jm =  1 + (int) (days / 31);
        let jd =  1 + (days % 31);
      } else {
        let jm =  7 + (int) ((days - 186) / 30);
        let jd =  1 + ((days - 186) % 30);
      }
      return (mod == "") ? [jy, jm, jd] : jy . mod . jm . mod . jd;
    }
    
    
    public function jalali_to_gregorian( var jy,  var jm,  var jd,  var mod = "") {
        var days, gy, gd, sal_a, gm;
       var tmpArro3cr = explode("_", this->tr_num(jy . "_" . jm . "_" . jd));
       let jy = array_shift(tmpArro3cr);
       let jm = array_shift(tmpArro3cr);
       let jd = array_shift(tmpArro3cr);
      let jy +=  1595;
      let days =  -355668 + (365 * jy) + (((int) (jy / 33)) * 8) + ((int) (((jy % 33) + 3) / 4)) + jd + ((jm < 7) ? (jm - 1) * 31 : ((jm - 7) * 30) + 186);
      let gy =  400 * ((int)(days / 146097));
      let days %=  146097;
      if (days > 36524) {
        let koss=days - 1;
        let gy +=  100 * ((int)(koss / 36524));
        let days %=  36524;
        let kosss=days+1;
        if (days >= 365)
        {
        let days=kosss;
        }
      }
      let gy +=  4 * ((int) (days / 1461));
      let days %=  1461;
      if (days > 365) {
        let gy +=  (int) ((days - 1) / 365);
        let days =  (days - 1) % 365;
      }
      let gd =  days + 1;
      let sal_a =  [0, 31, ((gy % 4 == 0 && gy % 100 != 0) || (gy % 400 == 0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
      let gm =  0;
      while (gm < 13 && gd > sal_a[gm])  {
      return (mod == "") ? [gy, gm, gd] : gy . mod . gm . mod . gd;
      }
    }
    
    }
    
    
    bug 
    opened by AngusDV 1
  • `string` variable ending up with `null`

    `string` variable ending up with `null`

        protected final function getSpecial(int special) -> string
        {
            string suffix = "";
    
            switch special {
                case 1:
                    let suffix = "alpha";
                    break;
                case 2:
                    let suffix = "beta";
                    break;
                case 3:
                    let suffix = "RC";
                    break;
            }
    
            return suffix;
        }
    

    The above returns null when special is other than 1, 2 or 3. If a default clause is added to the switch it makes no difference.

    Also adding

    let suffix = "";
    

    has no effect.

    If the variable is changed to var suffix then the code works (i.e. you get an empty string if special is 4)

    bug 
    opened by niden 0
  • isset function work abnormal

    isset function work abnormal

    The isset function in the Zephir and the pure PHP return different result.

    Zephir:

    var test; let test = null; var_dump(isset(test));

    var obj; let obj = new Obj; let obj->property = null; var_dump(isset(obj->property));

    Output: bool(true)

    Pure PHP:

    $test = null; var_dump(isset($test));

    $obj = new stdClass; $obj->property = null; var_dump(isset($obj->property));

    Output: bool(false)

    opened by navisoft 0
Releases(0.16.3)
Owner
Zephir Language
Zephir is a compiled high level language aimed to the creation of C-extensions for PHP
Zephir Language
:gem: Go! AOP PHP - modern aspect-oriented framework for the new level of software development

Go! Aspect-Oriented Framework for PHP Go! AOP is a modern aspect-oriented framework in plain PHP with rich features for the new level of software deve

Go! Aspect-Oriented Framework 1.6k Dec 29, 2022
🚀 Developing Rocketseat's Next Level Week (NLW#05) Application using PHP/Swoole + Hyperf

Inmana PHP ?? Developing Rocketseat 's Next Level Week (NLW#05) Application using Swoole + Hyperf. This is the app of the Elixir track. I know PHP/Swo

Leo Cavalcante 18 Jun 1, 2022
PHPStan Symfony Framework extensions and rules

PHPStan Symfony Framework extensions and rules PHPStan This extension provides following features: Provides correct return type for ContainerInterface

PHPStan 564 Dec 30, 2022
High performance, full-stack PHP framework delivered as a C extension.

Phalcon Framework Phalcon is an open source web framework delivered as a C extension for the PHP language providing high performance and lower resourc

The Phalcon PHP Framework 10.7k Jan 8, 2023
High-Performance Long-Living PHP Framework for modern enterprise application development

Documentation · Discord · Telegram · Twitter Spiral Framework is a High-Performance Long-Living Full-Stack framework and group of over sixty PSR-compa

Spiral Scout 1.4k Jan 1, 2023
Biny is a tiny, high-performance PHP framework for web applications

Biny is high performance. Framework comes default with response time of less than 1ms. Stand-alone QPS easily up to 3000.

Tencent 1.7k Dec 9, 2022
High performance HTTP Service Framework for PHP based on Workerman.

webman High performance HTTP Service Framework for PHP based on Workerman. Manual https://www.workerman.net/doc/webman Benchmarks https://www.techempo

walkor 1.3k Jan 2, 2023
🔥High Performance PHP Progressive Framework.

The Core Framework English | 中文 The QueryPHP Application QueryPHP is a modern, high performance PHP progressive framework, to provide a stable and rel

The QueryPHP Framework 306 Dec 14, 2022
💾 High-performance PHP application server, load-balancer and process manager written in Golang. RR2 releases repository.

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Spiral Scout 45 Nov 29, 2022
🤯 High-performance PHP application server, load-balancer and process manager written in Golang

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Spiral Scout 6.9k Jan 3, 2023
Spiral Framework is a High-Performance PHP/Go Full-Stack framework and group of over sixty PSR-compatible components

Spiral HTTP Application Skeleton Spiral Framework is a High-Performance PHP/Go Full-Stack framework and group of over sixty PSR-compatible components.

Spiral Scout 152 Dec 18, 2022
This package provides a high performance HTTP server to speed up your Laravel/Lumen application based on Swoole.

This package provides a high performance HTTP server to speed up your Laravel/Lumen application based on Swoole.

Swoole Taiwan 3.9k Jan 8, 2023
Kit is a lightweight, high-performance and event-driven web services framework that provides core components such as config, container, http, log and route.

Kit What is it Kit is a lightweight, high-performance and event-driven web services framework that provides core components such as config, container,

null 2 Sep 23, 2022
Jin microservices is a complete microservice demo based on PHP language + hyperf microservices framework

介绍 Jin-microservices是基于 php 语言 + hyperf 微服务 框架的完整微服务demo。 github:https://github.com/Double-Jin/jin-microservices gitee:https://gitee.com/ljj96/jin-mic

null 114 Dec 29, 2022
Provides TemplateView and TwoStepView using PHP as the templating language, with support for partials, sections, and helpers.

Aura View This package provides an implementation of the TemplateView and TwoStepView patterns using PHP itself as the templating language. It support

Aura for PHP 83 Jan 3, 2023
Phpactor Language Server

This package provides a platform for building a Language Server according to the Language Server Specification

Phpactor 27 Dec 24, 2022
PHP Kafka client is used in PHP-FPM and Swoole. PHP Kafka client supports 50 APIs, which might be one that supports the most message types ever.

longlang/phpkafka Introduction English | 简体中文 PHP Kafka client is used in PHP-FPM and Swoole. The communication protocol is based on the JSON file in

Swoole Project 235 Dec 31, 2022
FuelPHP v1.x is a simple, flexible, community driven PHP 5.3+ framework, based on the best ideas of other frameworks, with a fresh start! FuelPHP is fully PHP 7 compatible.

FuelPHP Version: 1.8.2 Website Release Documentation Release API browser Development branch Documentation Development branch API browser Support Forum

Fuel 1.5k Dec 28, 2022
An asynchronous event driven PHP socket framework. Supports HTTP, Websocket, SSL and other custom protocols. PHP>=5.3.

Workerman What is it Workerman is an asynchronous event-driven PHP framework with high performance to build fast and scalable network applications. Wo

walkor 10.2k Dec 31, 2022