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
A high-level machine learning and deep learning library for the PHP language.

Rubix ML A high-level machine learning and deep learning library for the PHP language. Developer-friendly API is delightful to use 40+ supervised and

Rubix 1.7k Jan 1, 2023
Rubix ML - A high-level machine learning and deep learning library for the PHP language.

A high-level machine learning and deep learning library for the PHP language. Developer-friendly API is delightful to use 40+ supervised and

Rubix 1.7k Jan 6, 2023
Mega list of 1 on 1 meeting questions compiled from a variety to sources

Mega list of 1 on 1 meeting questions compiled from a variety to sources

Vidal Graupera 9.1k Dec 29, 2022
Leaf's very own high-speed, high-performance server

[WIP] Leaf Eien Server Eien is Leaf's implementation of a high-speed, high-performance server based on powerful tools like Open Swoole and Swoole. Eie

Leaf Framework 8 Dec 28, 2022
This package is aimed to be a simplistic PHP workflow package that works in a similar fashion to GitHub Actions.

Workflow This package is aimed to be a simplistic PHP workflow package that works in a similar fashion to GitHub Actions. Installation To install this

Steve McDougall 4 Sep 26, 2022
An extension for PHPStan for adding analysis for PHP Language Extensions.

PHPStan PHP Language Extensions (currently in BETA) This is an extension for PHPStan for adding analysis for PHP Language Extensions. Language feature

Dave Liddament 9 Nov 30, 2022
Attributes to define PHP language extensions (to be enforced by static analysis)

PHP Language Extensions (currently in BETA) This library provides attributes for extending the PHP language (e.g. adding package visibility). The inte

Dave Liddament 70 Dec 19, 2022
MajorDoMo is an open-source DIY smarthome automation platform aimed to be used in multi-protocol and multi-services environment.

MajorDoMo (Major Domestic Module) is an open-source DIY smarthome automation platform aimed to be used in multi-protocol and multi-services environment. It is based on web-technologies stack and ready to be delivered to any modern device. It is very flexible in configuration with OOP paradigm used to set up automation rules and scripts. This platform can be installed on almost any personal computer running Windows or Linux OS.

Sergei Jeihala 369 Dec 30, 2022
A cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services.

Motan Overview Motan is a cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services. Related

Weibo R&D Open Source Projects 5.8k Dec 20, 2022
PHP Text Analysis is a library for performing Information Retrieval (IR) and Natural Language Processing (NLP) tasks using the PHP language

php-text-analysis PHP Text Analysis is a library for performing Information Retrieval (IR) and Natural Language Processing (NLP) tasks using the PHP l

null 464 Dec 28, 2022
A repository for showcasing my knowledge of the PHP programming language, and continuing to learn the language.

Learning PHP (programming language) I know very little about PHP. This document will list all my knowledge of the PHP programming language. Basic synt

Sean P. Myrick V19.1.7.2 2 Oct 29, 2022
S11 Selection est une solution web PHP faite pour automatiser la création d'une grille d'évaluation d'un étudiant puis de les rassembler pour en faire un classement.

[S11] SELECTION BTS 0.1.0 FR Description S11 Selection est une solution web PHP faite pour automatiser la création d'une grille d'évaluation d'un étud

NOIZET Maxence 1 Oct 25, 2022
Allows generate class files parse from json and map json to php object, including multi-level and complex objects;

nixihz/php-object Allows generate class files parse from json and map json to php object, including multi-level and complex objects; Installation You

zhixin 2 Sep 9, 2022
Helps detect the user's browser and platform at the PHP level via the user agent

cbschuld/browser.php Helps detect the user's browser and platform at the PHP level via the user agent Installation You can add this library as a local

Chris Schuld 574 Dec 16, 2022
A PHP package for calculating & tracking the Service Level Agreement completion timings

A PHP package for calculating & tracking the Service Level Agreement completion timings. Features ?? Easy schedule building ‼️ Defined breaches ?? Hol

Alex 26 Oct 5, 2022
Couleur is a modern PHP 8.1+ color library, intended to be compatible with CSS Color Module Level 4.

?? Couleur: A modern PHP 8.1+ color library ?? Couleur: A modern PHP 8.1+ color library ?? Presentation ⚙️ Installation ?? Quick Start ?? Usage ?? Imm

Matthieu Masta Denis 3 Oct 26, 2022