├── generated ├── Exceptions │ ├── .gitkeep │ ├── PsException.php │ ├── ApcuException.php │ ├── ArrayException.php │ ├── Bzip2Exception.php │ ├── ComException.php │ ├── DirException.php │ ├── EioException.php │ ├── ExecException.php │ ├── FpmException.php │ ├── FtpException.php │ ├── GmpException.php │ ├── GnupgException.php │ ├── HashException.php │ ├── IbaseException.php │ ├── IconvException.php │ ├── ImageException.php │ ├── ImapException.php │ ├── InfoException.php │ ├── LdapException.php │ ├── LzfException.php │ ├── MiscException.php │ ├── MysqlException.php │ ├── Oci8Exception.php │ ├── PcntlException.php │ ├── PgsqlException.php │ ├── PosixException.php │ ├── RrdException.php │ ├── SemException.php │ ├── ShmopException.php │ ├── SolrException.php │ ├── SplException.php │ ├── Ssh2Exception.php │ ├── UodbcException.php │ ├── UopzException.php │ ├── UrlException.php │ ├── VarException.php │ ├── XdiffException.php │ ├── XmlException.php │ ├── YamlException.php │ ├── YazException.php │ ├── ZipException.php │ ├── ZlibException.php │ ├── ApacheException.php │ ├── CubridException.php │ ├── FilterException.php │ ├── GettextException.php │ ├── IbmDb2Exception.php │ ├── InotifyException.php │ ├── LibxmlException.php │ ├── MysqliException.php │ ├── NetworkException.php │ ├── OpcacheException.php │ ├── PspellException.php │ ├── RpminfoException.php │ ├── SessionException.php │ ├── SocketsException.php │ ├── SqlsrvException.php │ ├── SsdeepException.php │ ├── StreamException.php │ ├── StringsException.php │ ├── SwooleException.php │ ├── XmlrpcException.php │ ├── CalendarException.php │ ├── ClassobjException.php │ ├── DatetimeException.php │ ├── ErrorfuncException.php │ ├── FileinfoException.php │ ├── FilesystemException.php │ ├── FunchandException.php │ ├── IngresiiException.php │ ├── MailparseException.php │ ├── MbstringException.php │ ├── MysqlndMsException.php │ ├── MysqlndQcException.php │ ├── OutcontrolException.php │ ├── PasswordException.php │ ├── ReadlineException.php │ └── SimplexmlException.php ├── rpminfo.php ├── solr.php ├── libxml.php ├── fpm.php ├── mysqli.php ├── xmlrpc.php ├── rrd.php ├── gettext.php ├── classobj.php ├── var.php ├── uopz.php ├── lzf.php ├── inotify.php ├── shmop.php ├── funchand.php ├── opcache.php ├── calendar.php ├── json.php ├── ssdeep.php ├── fileinfo.php ├── errorfunc.php ├── hash.php ├── gmp.php ├── bzip2.php ├── swoole.php ├── iconv.php ├── filter.php ├── apcu.php ├── mysqlndQc.php ├── simplexml.php ├── xml.php ├── mysqlndMs.php ├── zip.php ├── yaml.php ├── mailparse.php ├── password.php ├── outcontrol.php ├── readline.php ├── gnupg.php ├── dir.php ├── spl.php ├── pcntl.php ├── url.php ├── apache.php ├── exec.php ├── com.php └── xdiff.php ├── lib ├── Exceptions │ ├── SafeExceptionInterface.php │ ├── OpensslException.php │ ├── JsonException.php │ ├── CurlException.php │ └── PcreException.php ├── DateTime.php └── DateTimeImmutable.php ├── deprecated ├── Exceptions │ ├── ApcException.php │ ├── MssqlException.php │ ├── StatsException.php │ └── LibeventException.php ├── functionsList.php ├── stats.php └── apc.php ├── LICENSE ├── composer.json └── README.md /generated/Exceptions/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/Exceptions/SafeExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 'PREG_INTERNAL_ERROR: Internal error', 12 | PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR: Backtrack limit reached', 13 | PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR: Recursion limit reached', 14 | PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR: Invalid UTF8 character', 15 | PREG_BAD_UTF8_OFFSET_ERROR => 'PREG_BAD_UTF8_OFFSET_ERROR', 16 | PREG_JIT_STACKLIMIT_ERROR => 'PREG_JIT_STACKLIMIT_ERROR', 17 | ]; 18 | $errMsg = $errorMap[preg_last_error()] ?? 'Unknown PCRE error: '.preg_last_error(); 19 | return new self($errMsg, \preg_last_error()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /generated/uopz.php: -------------------------------------------------------------------------------- 1 | format('Y-m-d H:i:s.u'), $datetime->getTimezone()); 17 | } 18 | 19 | /** 20 | * @param string $format 21 | * @param string $time 22 | * @param DateTimeZone|null $timezone 23 | * @throws DatetimeException 24 | */ 25 | public static function createFromFormat($format, $time, $timezone = null): self 26 | { 27 | $datetime = parent::createFromFormat($format, $time, $timezone); 28 | if ($datetime === false) { 29 | throw DatetimeException::createFromPhpError(); 30 | } 31 | return self::createFromRegular($datetime); 32 | } 33 | 34 | /** 35 | * @param DateTimeInterface $datetime2 The date to compare to. 36 | * @param boolean $absolute [optional] Whether to return absolute difference. 37 | * @return DateInterval The DateInterval object representing the difference between the two dates. 38 | * @throws DatetimeException 39 | */ 40 | public function diff($datetime2, $absolute = false): DateInterval 41 | { 42 | /** @var \DateInterval|false $result */ 43 | $result = parent::diff($datetime2, $absolute); 44 | if ($result === false) { 45 | throw DatetimeException::createFromPhpError(); 46 | } 47 | return $result; 48 | } 49 | 50 | /** 51 | * @param string $modify A date/time string. Valid formats are explained in Date and Time Formats. 52 | * @return DateTime Returns the DateTime object for method chaining. 53 | * @throws DatetimeException 54 | */ 55 | public function modify($modify): self 56 | { 57 | /** @var DateTime|false $result */ 58 | $result = parent::modify($modify); 59 | if ($result === false) { 60 | throw DatetimeException::createFromPhpError(); 61 | } 62 | return $result; 63 | } 64 | 65 | /** 66 | * @param int $year 67 | * @param int $month 68 | * @param int $day 69 | * @return DateTime 70 | * @throws DatetimeException 71 | */ 72 | public function setDate($year, $month, $day): self 73 | { 74 | /** @var DateTime|false $result */ 75 | $result = parent::setDate($year, $month, $day); 76 | if ($result === false) { 77 | throw DatetimeException::createFromPhpError(); 78 | } 79 | return $result; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /generated/bzip2.php: -------------------------------------------------------------------------------- 1 | =8.0" 105 | }, 106 | "require-dev": { 107 | "phpstan/phpstan": "^0.12", 108 | "thecodingmachine/phpstan-strict-rules": "^0.12", 109 | "squizlabs/php_codesniffer": "^3.2" 110 | }, 111 | "scripts": { 112 | "phpstan": "phpstan analyse lib -c phpstan.neon --level=max --no-progress -vvv", 113 | "cs-fix": "phpcbf", 114 | "cs-check": "phpcs" 115 | }, 116 | "extra": { 117 | "branch-alias": { 118 | "dev-master": "0.1-dev" 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /generated/readline.php: -------------------------------------------------------------------------------- 1 | 63 | * ]]> 64 | * 65 | * 66 | * 67 | * @param string $prompt The prompt message. 68 | * @param callable $callback The callback function takes one parameter; the 69 | * user input returned. 70 | * @throws ReadlineException 71 | * 72 | */ 73 | function readline_callback_handler_install(string $prompt, callable $callback): void 74 | { 75 | error_clear_last(); 76 | $result = \readline_callback_handler_install($prompt, $callback); 77 | if ($result === false) { 78 | throw ReadlineException::createFromPhpError(); 79 | } 80 | } 81 | 82 | 83 | /** 84 | * This function clears the entire command line history. 85 | * 86 | * @throws ReadlineException 87 | * 88 | */ 89 | function readline_clear_history(): void 90 | { 91 | error_clear_last(); 92 | $result = \readline_clear_history(); 93 | if ($result === false) { 94 | throw ReadlineException::createFromPhpError(); 95 | } 96 | } 97 | 98 | 99 | /** 100 | * This function registers a completion function. This is the same kind of 101 | * functionality you'd get if you hit your tab key while using Bash. 102 | * 103 | * @param callable $callback You must supply the name of an existing function which accepts a 104 | * partial command line and returns an array of possible matches. 105 | * @throws ReadlineException 106 | * 107 | */ 108 | function readline_completion_function(callable $callback): void 109 | { 110 | error_clear_last(); 111 | $result = \readline_completion_function($callback); 112 | if ($result === false) { 113 | throw ReadlineException::createFromPhpError(); 114 | } 115 | } 116 | 117 | 118 | /** 119 | * This function reads a command history from a file. 120 | * 121 | * @param string $filename Path to the filename containing the command history. 122 | * @throws ReadlineException 123 | * 124 | */ 125 | function readline_read_history(string $filename = null): void 126 | { 127 | error_clear_last(); 128 | if ($filename !== null) { 129 | $result = \readline_read_history($filename); 130 | } else { 131 | $result = \readline_read_history(); 132 | } 133 | if ($result === false) { 134 | throw ReadlineException::createFromPhpError(); 135 | } 136 | } 137 | 138 | 139 | /** 140 | * This function writes the command history to a file. 141 | * 142 | * @param string $filename Path to the saved file. 143 | * @throws ReadlineException 144 | * 145 | */ 146 | function readline_write_history(string $filename = null): void 147 | { 148 | error_clear_last(); 149 | if ($filename !== null) { 150 | $result = \readline_write_history($filename); 151 | } else { 152 | $result = \readline_write_history(); 153 | } 154 | if ($result === false) { 155 | throw ReadlineException::createFromPhpError(); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /generated/gnupg.php: -------------------------------------------------------------------------------- 1 | 77 | * 78 | * 79 | * (pay attention to line endings - PHP uses a native function to 80 | * parse the input, so a Mac file won't work on Unix). 81 | * @param bool $use_include_path Setting use_include_path to TRUE will result 82 | * in PHP trying to open the file along the standard include path as per 83 | * the include_path directive. 84 | * This is used for local files, not URLs. 85 | * @return array Returns an array with all the parsed meta tags. 86 | * 87 | * The value of the name property becomes the key, the value of the content 88 | * property becomes the value of the returned array, so you can easily use 89 | * standard array functions to traverse it or access single values. 90 | * Special characters in the value of the name property are substituted with 91 | * '_', the rest is converted to lower case. If two meta tags have the same 92 | * name, only the last one is returned. 93 | * 94 | * Returns FALSE on failure. 95 | * @throws UrlException 96 | * 97 | */ 98 | function get_meta_tags(string $filename, bool $use_include_path = false): array 99 | { 100 | error_clear_last(); 101 | $result = \get_meta_tags($filename, $use_include_path); 102 | if ($result === false) { 103 | throw UrlException::createFromPhpError(); 104 | } 105 | return $result; 106 | } 107 | 108 | 109 | /** 110 | * This function parses a URL and returns an associative array containing any 111 | * of the various components of the URL that are present. 112 | * The values of the array elements are not URL decoded. 113 | * 114 | * This function is not meant to validate 115 | * the given URL, it only breaks it up into the above listed parts. Partial 116 | * URLs are also accepted, parse_url tries its best to 117 | * parse them correctly. 118 | * 119 | * @param string $url The URL to parse. Invalid characters are replaced by 120 | * _. 121 | * @param int $component Specify one of PHP_URL_SCHEME, 122 | * PHP_URL_HOST, PHP_URL_PORT, 123 | * PHP_URL_USER, PHP_URL_PASS, 124 | * PHP_URL_PATH, PHP_URL_QUERY 125 | * or PHP_URL_FRAGMENT to retrieve just a specific 126 | * URL component as a string (except when 127 | * PHP_URL_PORT is given, in which case the return 128 | * value will be an int). 129 | * @return mixed On seriously malformed URLs, parse_url. 130 | * 131 | * If the component parameter is omitted, an 132 | * associative array is returned. At least one element will be 133 | * present within the array. Potential keys within this array are: 134 | * 135 | * 136 | * 137 | * scheme - e.g. http 138 | * 139 | * 140 | * 141 | * 142 | * host 143 | * 144 | * 145 | * 146 | * 147 | * port 148 | * 149 | * 150 | * 151 | * 152 | * user 153 | * 154 | * 155 | * 156 | * 157 | * pass 158 | * 159 | * 160 | * 161 | * 162 | * path 163 | * 164 | * 165 | * 166 | * 167 | * query - after the question mark ? 168 | * 169 | * 170 | * 171 | * 172 | * fragment - after the hashmark # 173 | * 174 | * 175 | * 176 | * 177 | * If the component parameter is specified, 178 | * parse_url returns a string (or an 179 | * int, in the case of PHP_URL_PORT) 180 | * instead of an array. If the requested component doesn't exist 181 | * within the given URL, NULL will be returned. 182 | * @throws UrlException 183 | * 184 | */ 185 | function parse_url(string $url, int $component = -1) 186 | { 187 | error_clear_last(); 188 | $result = \parse_url($url, $component); 189 | if ($result === false) { 190 | throw UrlException::createFromPhpError(); 191 | } 192 | return $result; 193 | } 194 | -------------------------------------------------------------------------------- /generated/apache.php: -------------------------------------------------------------------------------- 1 | Yeah... but I must explicitly think about importing the "safe" variant of the function, for each and every file of my application. 76 | > I'm sure I will forget some "use function" statements! 77 | 78 | Fear not! thecodingmachine/safe comes with a PHPStan rule. 79 | 80 | Never heard of [PHPStan](https://github.com/phpstan/phpstan) before? 81 | Check it out, it's an amazing code analyzer for PHP. 82 | 83 | Simply install the Safe rule in your PHPStan setup (explained in the "Installation" section) and PHPStan will let you know each time you are using an "unsafe" function. 84 | 85 | The code below will trigger this warning: 86 | 87 | ```php 88 | $content = file_get_contents('foobar.json'); 89 | ``` 90 | 91 | > Function file_get_contents is unsafe to use. It can return FALSE instead of throwing an exception. Please add 'use function Safe\\file_get_contents;' at the beginning of the file to use the variant provided by the 'thecodingmachine/safe' library. 92 | 93 | ## Installation 94 | 95 | Use composer to install Safe-PHP: 96 | 97 | ```bash 98 | $ composer require thecodingmachine/safe 99 | ``` 100 | 101 | *Highly recommended*: install PHPStan and PHPStan extension: 102 | 103 | ```bash 104 | $ composer require --dev thecodingmachine/phpstan-safe-rule 105 | ``` 106 | 107 | Now, edit your `phpstan.neon` file and add these rules: 108 | 109 | ```yml 110 | includes: 111 | - vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon 112 | ``` 113 | 114 | ## Automated refactoring 115 | 116 | You have a large legacy codebase and want to use "Safe-PHP" functions throughout your project? PHPStan will help you 117 | find these functions but changing the namespace of the functions one function at a time might be a tedious task. 118 | 119 | Fortunately, Safe comes bundled with a "Rector" configuration file. [Rector](https://github.com/rectorphp/rector) is a command-line 120 | tool that performs instant refactoring of your application. 121 | 122 | Run 123 | 124 | ```bash 125 | $ composer require --dev rector/rector:^0.7 126 | ``` 127 | 128 | to install `rector/rector`. 129 | 130 | Run 131 | 132 | ```bash 133 | vendor/bin/rector process src/ --config vendor/thecodingmachine/safe/rector-migrate-0.7.php 134 | ``` 135 | 136 | to run `rector/rector`. 137 | 138 | *Note:* do not forget to replace "src/" with the path to your source directory. 139 | 140 | **Important:** the refactoring only performs a "dumb" replacement of functions. It will not modify the way 141 | "false" return values are handled. So if your code was already performing error handling, you will have to deal 142 | with it manually. 143 | 144 | Especially, you should look for error handling that was already performed, like: 145 | 146 | ```php 147 | if (!mkdir($dirPath)) { 148 | // Do something on error 149 | } 150 | ``` 151 | 152 | This code will be refactored by Rector to: 153 | 154 | ```php 155 | if (!\Safe\mkdir($dirPath)) { 156 | // Do something on error 157 | } 158 | ``` 159 | 160 | You should then (manually) refactor it to: 161 | 162 | ```php 163 | try { 164 | \Safe\mkdir($dirPath)); 165 | } catch (\Safe\FilesystemException $e) { 166 | // Do something on error 167 | } 168 | ``` 169 | 170 | ## Performance impact 171 | 172 | Safe is loading 1000+ functions from ~85 files on each request. Yet, the performance impact of this loading is quite low. 173 | 174 | In case you worry, using Safe will "cost" you ~700µs on each request. The [performance section](performance/README.md) 175 | contains more information regarding the way we tested the performance impact of Safe. 176 | 177 | ## Learn more 178 | 179 | Read [the release article on TheCodingMachine's blog](https://thecodingmachine.io/introducing-safe-php) if you want to 180 | learn more about what triggered the development of Safe-PHP. 181 | 182 | ## Contributing 183 | 184 | The files that contain all the functions are auto-generated from the PHP doc. 185 | Read the [CONTRIBUTING.md](CONTRIBUTING.md) file to learn how to regenerate these files and to contribute to this library. 186 | -------------------------------------------------------------------------------- /deprecated/apc.php: -------------------------------------------------------------------------------- 1 | innerDateTime = new parent($time, $timezone); 33 | } 34 | 35 | //switch between regular datetime and safe version 36 | public static function createFromRegular(\DateTimeImmutable $datetime): self 37 | { 38 | $safeDatetime = new self($datetime->format('Y-m-d H:i:s.u'), $datetime->getTimezone()); //we need to also update the wrapper to not break the operators '<' and '>' 39 | $safeDatetime->innerDateTime = $datetime; //to make sure we don't lose information because of the format(). 40 | return $safeDatetime; 41 | } 42 | 43 | //usefull if you need to switch back to regular DateTimeImmutable (for example when using DatePeriod) 44 | public function getInnerDateTime(): \DateTimeImmutable 45 | { 46 | return $this->innerDateTime; 47 | } 48 | 49 | ///////////////////////////////////////////////////////////////////////////// 50 | // overload functions with false errors 51 | 52 | /** 53 | * @param string $format 54 | * @param string $time 55 | * @param DateTimeZone|null $timezone 56 | * @throws DatetimeException 57 | */ 58 | public static function createFromFormat($format, $time, $timezone = null) 59 | { 60 | $datetime = \DateTimeImmutable::createFromFormat($format, $time, $timezone); 61 | if ($datetime === false) { 62 | throw DatetimeException::createFromPhpError(); 63 | } 64 | return self::createFromRegular($datetime); 65 | } 66 | 67 | /** 68 | * @param string $format 69 | * @return string 70 | * @throws DatetimeException 71 | */ 72 | public function format($format): string 73 | { 74 | /** @var string|false $result */ 75 | $result = $this->innerDateTime->format($format); 76 | if ($result === false) { 77 | throw DatetimeException::createFromPhpError(); 78 | } 79 | return $result; 80 | } 81 | 82 | /** 83 | * @param DateTimeInterface $datetime2 84 | * @param bool $absolute 85 | * @return DateInterval 86 | * @throws DatetimeException 87 | */ 88 | public function diff($datetime2, $absolute = false): DateInterval 89 | { 90 | /** @var \DateInterval|false $result */ 91 | $result = $this->innerDateTime->diff($datetime2, $absolute); 92 | if ($result === false) { 93 | throw DatetimeException::createFromPhpError(); 94 | } 95 | return $result; 96 | } 97 | 98 | /** 99 | * @param string $modify 100 | * @return DateTimeImmutable 101 | * @throws DatetimeException 102 | */ 103 | public function modify($modify): self 104 | { 105 | /** @var \DateTimeImmutable|false $result */ 106 | $result = $this->innerDateTime->modify($modify); 107 | if ($result === false) { 108 | throw DatetimeException::createFromPhpError(); 109 | } 110 | return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable 111 | } 112 | 113 | /** 114 | * @param int $year 115 | * @param int $month 116 | * @param int $day 117 | * @return DateTimeImmutable 118 | * @throws DatetimeException 119 | */ 120 | public function setDate($year, $month, $day): self 121 | { 122 | /** @var \DateTimeImmutable|false $result */ 123 | $result = $this->innerDateTime->setDate($year, $month, $day); 124 | if ($result === false) { 125 | throw DatetimeException::createFromPhpError(); 126 | } 127 | return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable 128 | } 129 | 130 | /** 131 | * @param int $year 132 | * @param int $week 133 | * @param int $day 134 | * @return DateTimeImmutable 135 | * @throws DatetimeException 136 | */ 137 | public function setISODate($year, $week, $day = 1): self 138 | { 139 | /** @var \DateTimeImmutable|false $result */ 140 | $result = $this->innerDateTime->setISODate($year, $week, $day); 141 | if ($result === false) { 142 | throw DatetimeException::createFromPhpError(); 143 | } 144 | return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable 145 | } 146 | 147 | /** 148 | * @param int $hour 149 | * @param int $minute 150 | * @param int $second 151 | * @param int $microseconds 152 | * @return DateTimeImmutable 153 | * @throws DatetimeException 154 | */ 155 | public function setTime($hour, $minute, $second = 0, $microseconds = 0): self 156 | { 157 | /** @var \DateTimeImmutable|false $result */ 158 | $result = $this->innerDateTime->setTime($hour, $minute, $second, $microseconds); 159 | if ($result === false) { 160 | throw DatetimeException::createFromPhpError(); 161 | } 162 | return self::createFromRegular($result); 163 | } 164 | 165 | /** 166 | * @param int $unixtimestamp 167 | * @return DateTimeImmutable 168 | * @throws DatetimeException 169 | */ 170 | public function setTimestamp($unixtimestamp): self 171 | { 172 | /** @var \DateTimeImmutable|false $result */ 173 | $result = $this->innerDateTime->setTimestamp($unixtimestamp); 174 | if ($result === false) { 175 | throw DatetimeException::createFromPhpError(); 176 | } 177 | return self::createFromRegular($result); 178 | } 179 | 180 | /** 181 | * @param DateTimeZone $timezone 182 | * @return DateTimeImmutable 183 | * @throws DatetimeException 184 | */ 185 | public function setTimezone($timezone): self 186 | { 187 | /** @var \DateTimeImmutable|false $result */ 188 | $result = $this->innerDateTime->setTimezone($timezone); 189 | if ($result === false) { 190 | throw DatetimeException::createFromPhpError(); 191 | } 192 | return self::createFromRegular($result); 193 | } 194 | 195 | /** 196 | * @param DateInterval $interval 197 | * @return DateTimeImmutable 198 | * @throws DatetimeException 199 | */ 200 | public function sub($interval): self 201 | { 202 | /** @var \DateTimeImmutable|false $result */ 203 | $result = $this->innerDateTime->sub($interval); 204 | if ($result === false) { 205 | throw DatetimeException::createFromPhpError(); 206 | } 207 | return self::createFromRegular($result); 208 | } 209 | 210 | /** 211 | * @throws DatetimeException 212 | */ 213 | public function getOffset(): int 214 | { 215 | /** @var int|false $result */ 216 | $result = $this->innerDateTime->getOffset(); 217 | if ($result === false) { 218 | throw DatetimeException::createFromPhpError(); 219 | } 220 | return $result; 221 | } 222 | 223 | ////////////////////////////////////////////////////////////////////////////////////////// 224 | //overload getters to use the inner datetime immutable instead of itself 225 | 226 | /** 227 | * @param DateInterval $interval 228 | * @return DateTimeImmutable 229 | */ 230 | public function add($interval): self 231 | { 232 | return self::createFromRegular($this->innerDateTime->add($interval)); 233 | } 234 | 235 | /** 236 | * @param DateTime $dateTime 237 | * @return DateTimeImmutable 238 | */ 239 | public static function createFromMutable($dateTime): self 240 | { 241 | return self::createFromRegular(parent::createFromMutable($dateTime)); 242 | } 243 | 244 | /** 245 | * @param mixed[] $array 246 | * @return DateTimeImmutable 247 | */ 248 | public static function __set_state($array): self 249 | { 250 | return self::createFromRegular(parent::__set_state($array)); 251 | } 252 | 253 | public function getTimezone(): DateTimeZone 254 | { 255 | return $this->innerDateTime->getTimezone(); 256 | } 257 | 258 | public function getTimestamp(): int 259 | { 260 | return $this->innerDateTime->getTimestamp(); 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /generated/xdiff.php: -------------------------------------------------------------------------------- 1 |