├── .github └── workflows │ └── gh-pages.yml ├── .gitignore ├── README.md ├── command ├── html ├── all.html ├── changed-functions.html ├── changes.html ├── class-constants.html ├── classes.html ├── cli-cgi.html ├── configuration.html ├── constants.html ├── databases.html ├── datetime.html ├── deprecated.html ├── error-messages.html ├── errorcheck.html ├── errorrep.html ├── extensions-other.html ├── extensions.html ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── favicon.ico ├── features.html ├── functions.html ├── global-constants.html ├── images │ ├── bg-texture-00.svg │ ├── mobile-menu.png │ ├── search-sprites.png │ └── social.png ├── incompatible.html ├── index.html ├── ini.html ├── integer-parameters.html ├── internals.html ├── methods.html ├── newconf.html ├── oop.html ├── openssl.html ├── other-changes.html ├── other.html ├── parameters.html ├── phpnet.css ├── reading.html ├── references.html ├── removed-extensions.html ├── removed-exts-sapis.html ├── sapi-changes.html ├── sapi.html ├── stream-filters.html ├── stream-wrappers.html ├── styles.css ├── undeprecated.html ├── windows-support.html └── windows.html └── src ├── Command ├── All.php ├── Asset.php ├── AssetCss.php ├── AssetFavicon.php ├── AssetImages.php ├── Cache.php ├── Chunk.php ├── CommandAbstract.php ├── Html.php ├── HtmlAll.php ├── HtmlGroup.php └── HtmlIndex.php ├── Console ├── Command.php └── Message.php ├── Error ├── Error.php ├── ErrorAbstract.php ├── Exception.php └── Shutdown.php ├── Filesystem ├── Directory.php └── File.php ├── Html └── Dom.php ├── View └── Template.php ├── autoload.php ├── bootstrap.php └── views ├── assets ├── css │ └── styles.css ├── favicon │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ └── favicon.ico └── images │ └── social.png └── templates ├── index.php ├── info-version.php ├── info.php └── layout.php /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Publish to GH Pages 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | with: 15 | persist-credentials: false 16 | 17 | - name: Deploy 18 | uses: crazy-max/ghaction-github-pages@v2.0.1 19 | with: 20 | build_dir: html 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /cache 2 | 3 | .php_cs.cache -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP changes cheatsheet 2 | 3 | ## Build Requirements: 4 | 5 | - PHP 7.4 6 | 7 | ## Installation: 8 | 9 | - Clone this repo: `git clone https://github.com/eusonlito/php-changes-reference.git` 10 | - Generate all files with: `php command All` 11 | - Or, execute step by step: 12 | - Create cache: `php command Cache` 13 | - Create HTML chunks: `php command Chunk` 14 | - Create HTML files: `php command Html` 15 | - Create Assets: `php command Asset` 16 | - Open file `html/index.html` 17 | -------------------------------------------------------------------------------- /command: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 2 | 3 | 4 | 5 | 6 | 7 | What has changed in PHP 5.5, 5.4, 5.3, 5.2, 5.1, 5.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.5

50 |
51 | 52 |
53 |

What has changed in PHP 5.5.x

54 |

55 | Most improvements in PHP 5.5.x have no impact on existing code. There are 56 | a few incompatibilities 57 | and new features that should 58 | be considered, and code should be tested before switching PHP 59 | versions in production environments. 60 |

61 |

62 | For systems being upgraded from an older version of PHP, the relevant 63 | documentation is available at: 64 |

65 |
91 |
92 |

PHP 5.4

93 |
94 | 95 |
96 |

What has changed in PHP 5.4.x

97 |

98 | Most improvements in PHP 5.4.x have no impact on existing code. There are 99 | a few incompatibilities 100 | and new features that should 101 | be considered, and code should be tested before switching PHP 102 | versions in production environments. 103 |

104 |

105 | For systems being upgraded from an older version of PHP, the relevant 106 | documentation is available at: 107 |

108 |
129 |
130 |

PHP 5.3

131 |
132 | 133 |
134 |

What has changed in PHP 5.3.x

135 |

136 | Most improvements in PHP 5.3.x have no impact on existing code. There are 137 | a few incompatibilities 138 | and new features that should 139 | be considered, and code should be tested before switching PHP 140 | versions in production environments. 141 |

142 |

143 | For systems being upgraded from an older version of PHP, the relevant 144 | documentation is available at: 145 |

146 |
162 |
163 |

PHP 5.2

164 |
165 | 166 |
167 |

What has changed in PHP 5.2.x

168 |

169 | Most improvements in PHP 5.2.x have no impact on existing code. There are 170 | a few incompatibilities 171 | and new error messages 172 | that should be considered, and code should be tested before switching PHP 173 | versions in production environments. 174 |

175 |

176 | If the system is being upgraded from PHP 5.0.x, the manual section titled 177 | Upgrade Notes for PHP 5.1.x 178 | should also be read. 179 |

180 |

181 | Similarly, if the system is being upgraded from PHP 4, the manual section 182 | titled Migrating from PHP 4 to PHP 5 183 | should be read as well. 184 |

185 |
186 |
187 |

PHP 5.1

188 |
189 | 190 |
191 |

Key PHP 5.1.x features

192 |

193 | Some of the key features of PHP 5.1.x include: 194 |

195 |
  • 196 |

    197 | A complete rewrite of date handling code, with improved timezone support. 198 |

    199 |
  • 200 |
  • 201 |

    202 | Significant performance improvements compared to PHP 5.0.X. 203 |

    204 |
  • 205 |
  • 206 |

    207 | PDO extension is now enabled by default. 208 |

    209 |
  • 210 |
  • 211 |

    212 | Over 30 new functions in various extensions and built-in functionality. 213 |

    214 |
  • 215 |
  • 216 |

    217 | Over 400 various bug fixes. 218 |

    219 |
  • 220 |
221 |
222 |

PHP 5.0

223 |
224 | 225 |
226 |

What has changed in PHP 5.0.x

227 |

228 | PHP 5 and the integrated Zend Engine 2 have greatly improved PHP's 229 | performance and capabilities, but great care has been taken to break as 230 | little existing code as possible. So migrating your code from PHP 4 to 5 231 | should be very easy. Most existing PHP 4 code should be ready to run 232 | without changes, but you should still know about the few differences and 233 | take care to test your code before switching versions in production 234 | environments. 235 |

236 |
237 |
238 | 239 | -------------------------------------------------------------------------------- /html/class-constants.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | New Class Constants in PHP 5.3, 5.2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.3

50 |
51 | 52 |
53 |

New Class Constants

54 |

55 | Several new class constants were introduced in 5.3.0: 56 |

57 | 58 |

PDO_FIREBIRD:

59 |
  • 60 | 61 | PDO::FB_ATTR_DATE_FORMAT 62 | - Sets the format for dates. 63 | 64 |
  • 65 |
  • 66 | 67 | PDO::FB_ATTR_TIME_FORMAT 68 | - Sets the format for time. 69 | 70 |
  • 71 |
  • 72 | 73 | PDO::FB_ATTR_TIMESTAMP_FORMAT 74 | - Sets the format for timestamps. 75 | 76 |
  • 77 |
78 |
79 |

PHP 5.2

80 |
81 | 82 |
83 |

New Class Constants

84 | 85 |

pdo:

86 |
  • 87 | 88 | PDO::ATTR_DEFAULT_FETCH_MODE 89 | 90 |
  • 91 |
  • 92 | 93 | PDO::FETCH_PROPS_LATE 94 | 95 |
  • 96 |
  • 97 | 98 | PDO::FETCH_KEY_PAIR 99 | 100 | 101 | Fetches a 2 column result set into an associated array. (Added in PHP 5.2.3) 102 | 103 |
  • 104 |

spl:

105 |
  • 106 | 107 | CachingIterator::FULL_CACHE 108 | 109 |
  • 110 |
  • 111 | 112 | CachingIterator::TOSTRING_USE_INNER 113 | 114 |
  • 115 |
  • 116 | 117 | SplFileObject::READ_AHEAD 118 | 119 |
  • 120 |
  • 121 | 122 | SplFileObject::READ_CSV 123 | 124 |
  • 125 |
  • 126 | 127 | SplFileObject::SKIP_EMPTY 128 | 129 |
  • 130 |
131 |
132 | 133 | -------------------------------------------------------------------------------- /html/cli-cgi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CLI and CGI in PHP 5.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.0

50 |
51 | 52 |
53 |

CLI and CGI

54 |

55 | In PHP 5 there were some changes in CLI and CGI filenames. In PHP 5, the 56 | CGI version was renamed to php-cgi.exe (previously 57 | php.exe) and the CLI version now sits in the main 58 | directory (previously cli/php.exe). 59 |

60 |

61 | In PHP 5 it was also introduced a new mode: 62 | php-win.exe. This is equal to the CLI version, except 63 | that php-win doesn't output anything and thus provides no console (no "dos 64 | box" appears on the screen). This behavior is similar to php-gtk. 65 |

66 |

67 | In PHP 5, the CLI version will always populate the global 68 | $argv and $argc variables regardless 69 | of any php.ini directive setting. Even having 70 | register_argc_argv set to 71 | off will have no affect in CLI. 72 |

73 |

74 | See also the command line 75 | reference. 76 |

77 |
78 |
79 | 80 | -------------------------------------------------------------------------------- /html/configuration.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Migrating Configuration Files in PHP 5.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.0

50 |
51 | 52 |
53 |

Migrating Configuration Files

54 |

55 | Since the ISAPI modules changed their names, from php4xxx to php5xxx, you 56 | need to make some changes in the configuration files. There were also 57 | changes in the CLI and CGI filenames. Please refer to the corresponding section for more 58 | information. 59 |

60 |

61 | Migrating the Apache configuration is extremely easy. See the example below 62 | to check the change you need to do: 63 |

64 |

Example #1 Migrating Apache configuration files for PHP 5

65 |
66 |
# change this line:    
 67 | LoadModule php4_module /php/sapi/php4apache2.dll
 68 | 
 69 | # with this one:
 70 | LoadModule php5_module /php/php5apache2.dll
71 |
72 |
73 | 74 |
75 | 76 |

77 | If your web server is running PHP in CGI mode, you should note that the 78 | CGI version has changed its name from php.exe to 79 | php-cgi.exe. 80 | In Apache, you should do something like this: 81 |

82 |

Example #2 Migrating Apache configuration files for PHP 5, CGI mode

83 |
84 |
# change this line:    
 85 | Action application/x-httpd-php "/php/php.exe" 
 86 | 
 87 | # with this one:
 88 | Action application/x-httpd-php "/php/php-cgi.exe"
89 |
90 |
91 | 92 |
93 | 94 |

95 | In other web servers you need to change either the CGI or the ISAPI module 96 | filenames. 97 |

98 |
99 |
100 | 101 | -------------------------------------------------------------------------------- /html/databases.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Changes in database support in PHP 5.1, 5.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.1

50 |
51 | 52 |
53 |

Changes in database support

54 |
70 |

PDO overview

71 |

72 | PHP Data Objects (PDO) were introduced as a 73 | PECL extension under PHP 5.0, and became part of the core PHP distribution 74 | in PHP 5.1.x. The PDO extension provides a consistent interface for database 75 | access, and is used alongside database-specific PDO drivers. Each driver 76 | may also have database-specific functions of its own, but basic data 77 | access functionality such as issuing queries and fetching data is covered 78 | by PDO functions, using the driver named in 79 | PDO::__construct(). 80 |

81 |

82 | Note that the PDO extension, and its drivers, are intended to be built as 83 | shared extensions. This will enable straightforward driver upgrades from 84 | PECL, without forcing you to rebuild all of PHP. 85 |

86 |

87 | At the point of the PHP 5.1.x release, PDO is more than ready for widespread 88 | testing and could be adopted in most situations. However, it is important 89 | to understand that PDO and its drivers are comparatively young and may be 90 | missing certain database-specific features; evaluate PDO carefully before 91 | you use it in new projects. 92 |

93 |

94 | Legacy code will generally rely on the pre-existing database extensions, 95 | which are still maintained. 96 |

97 |
98 | 99 |
100 |

Changes in MySQL support

101 |

102 | In PHP 4, MySQL 3 support was built-in. With the release of PHP 5.0 there 103 | were two MySQL extensions, named 'mysql' and 'mysqli', which were designed 104 | to support MySQL < 4.1 and MySQL 4.1 and up, respectively. With the 105 | introduction of PDO, which provides a very fast interface to all the 106 | database APIs supported by PHP, the PDO_MYSQL driver can support any of 107 | the current versions (MySQL 3, 4 or 5) in PHP code written for PDO, 108 | depending on the MySQL library version used during compilation. The older 109 | MySQL extensions remain in place for reasons of back compatibility, but 110 | are not enabled by default. 111 |

112 |
113 | 114 |
115 |

Changes in SQLite support

116 |

117 | In PHP 5.0.x, SQLite 2 support was provided by the built-in sqlite 118 | extension, which was also available as a PECL extension in PHP 4.3 and PHP 119 | 4.4. With the introduction of PDO, the sqlite extension doubles up to act 120 | as a 'sqlite2' driver for PDO; it is due to this that the sqlite extension 121 | in PHP 5.1.x has a dependency upon the PDO extension. 122 |

123 |

124 | PHP 5.1.x ships with a number of alternative interfaces to sqlite: 125 |

126 |

127 | The sqlite extension provides the "classic" sqlite procedural/OO API that 128 | you may have used in prior versions of PHP. It also provides the PDO 129 | 'sqlite2' driver, which allows you to access legacy SQLite 2 databases 130 | using the PDO API. 131 |

132 |

133 | PDO_SQLITE provides the 'sqlite' version 3 driver. SQLite version 3 is 134 | vastly superior to SQLite version 2, but the file formats of the two 135 | versions are not compatible. 136 |

137 |

138 | If your SQLite-based project is already written and working against 139 | earlier PHP versions, then you can continue to use ext/sqlite without 140 | problems, but will need to explicitly enable both PDO and sqlite. New 141 | projects should use PDO and the 'sqlite' (version 3) driver, as this is 142 | faster than SQLite 2, has improved locking concurrency, and supports both 143 | prepared statements and binary columns natively. 144 |

145 |

146 | You must enable PDO to use the SQLite extension. If you want to build the 147 | PDO extension as a shared extension, then the SQLite extension must also 148 | be built shared. The same holds true for any extension that provides a PDO 149 | driver 150 |

151 |
152 |
153 |
154 |

PHP 5.0

155 |
156 | 157 |
158 |

Databases

159 |

160 | There were some changes in PHP 5 regarding databases (MySQL and SQLite). 161 |

162 |

163 | In PHP 5 the MySQL client libraries are not bundled, because of license 164 | and maintenance problems. MySQL is supported with the only 165 | change being that MySQL support is no longer enabled by 166 | default in PHP 5. This essentially means that 167 | PHP doesn't include the --with-mysql 168 | option in the configure line so 169 | that you must now manually do this when compiling PHP. Windows users will 170 | need to edit php.ini and enable the php_mysql.dll 171 | DLL as in PHP 4 no such DLL existed, it was simply built into your Windows 172 | PHP binaries. 173 |

174 |

175 | There is also a new extension, MySQLi (Improved 176 | MySQL), which is designed to work with MySQL 4.1 and above. 177 |

178 |

179 | Since PHP 5, the SQLite extension is 180 | built-in PHP. SQLite is an embeddable SQL database engine and is not a 181 | client library used to connect to a big database server (like MySQL or 182 | PostgreSQL). The SQLite library reads and writes directly to and from the 183 | database files on disk. 184 |

185 |
186 |
187 | 188 | -------------------------------------------------------------------------------- /html/datetime.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Changes in PHP 5.2, 5.1 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.2

50 |
51 | 52 |
53 |

Changes in PHP datetime 54 | support

55 | 56 |

57 | Since PHP 5.1.0, there has been an extension named date 58 | in the PHP core. This is the new implementation of PHP's datetime support. 59 | Although it will attempt to guess your system's timezone setting, you 60 | should set the timezone manually. You can do this in any of three ways: 61 |

62 |
  • 63 | 64 | in your php.ini using the 65 | date.timezone INI directive 66 | 67 |
  • 68 |
  • 69 | 70 | on your system using the TZ environmental variable 71 | 72 |
  • 73 |
  • 74 | 75 | from your script using the convenience function 76 | date_default_timezone_set() 77 | 78 |
  • 79 |

80 | All supported timezones are listed 81 | in the PHP Manual. 82 |

83 |

84 | With the advent of PHP 5.2.x, there are object representations of the 85 | date and timezone, named DateTime and DateTimeZone respectively. 86 | The methods map to existing procedural date functions. 87 |

88 |
89 |
90 |

PHP 5.1

91 |
92 | 93 |
94 |

Date/time support

95 |

96 | Date/time support has been fully rewritten in PHP 5.1.x, and no longer uses 97 | the system settings to 'know' the timezone in operation. It will instead 98 | utilize, in the following order: 99 |

100 |
  • 101 |

    102 | The timezone set using the date_default_timezone_set() 103 | function (if any) 104 |

    105 |
  • 106 |
  • 107 |

    108 | The TZ environment variable (if non empty) 109 |

    110 |
  • 111 |
  • 112 |

    113 | "magical" guess (if the operating system supports it) 114 |

    115 |
  • 116 |
  • 117 |

    118 | If none of the above options succeeds, UTC 119 |

    120 |
  • 121 |
122 |

123 | To ensure accuracy (and avoid an E_STRICT warning), 124 | you will need to define your timezone in your php.ini 125 | using the following format: 126 |

127 |

128 | date.timezone = Europe/London 129 |

130 |
131 |

132 | The supported timezones are listed, in this format, in the 133 | timezones appendix. 134 |

135 |

136 | Also note that strtotime() now returns FALSE on 137 | failure, instead of -1. 138 |

139 |
140 |
141 | 142 | -------------------------------------------------------------------------------- /html/errorcheck.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Checking for E_STRICT in PHP 5.1 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.1

50 |
51 | 52 |
53 |

Checking for E_STRICT

54 |
55 |

56 | If you only have a single script to check, you can pick up 57 | E_STRICT errors using PHP's commandline lint 58 | facility: 59 |

60 |
php -d error_reporting=4095 -l script_to_check.php
61 |
62 | 63 |

64 | For larger projects, the shell script below will achieve the same task: 65 |

66 |
67 |
#!/bin/sh
 68 | 
 69 | directory=$1
 70 | 
 71 | shift
 72 | 
 73 | # These extensions are checked
 74 | extensions="php inc"
 75 | 
 76 | check_file ()
 77 | {
 78 |   echo -ne "Doing PHP syntax check on $1 ..."
 79 | 
 80 |   # Options:
 81 |   ERRORS=`/www/php/bin/php -d display_errors=1 -d html_errors=0 -d error_prepend_string=" " -d error_append_string=" " -d error_reporting=4095 -l $1 | grep -v "No syntax errors detected"`
 82 | 
 83 |   if test -z "$ERRORS"; then
 84 |     echo -ne "OK."
 85 |   else
 86 |     echo -e "Errors found!\n$ERRORS"
 87 |   fi
 88 | 
 89 |   echo
 90 | }
 91 | 
 92 | # loop over remaining file args
 93 | for FILE in "$@" ; do
 94 |   for ext in $extensions; do
 95 |      if echo $FILE | grep "\.$ext$" > /dev/null; then
 96 |        if test -f $FILE; then
 97 |          check_file "$FILE"
 98 |        fi
 99 |      fi
100 |   done
101 | done
102 |
103 |
104 | 105 |
106 |
107 |
108 | 109 | -------------------------------------------------------------------------------- /html/errorrep.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Error Reporting in PHP 5.2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.2

50 |
51 | 52 |
53 |

Error Reporting

54 |

55 | Some of the existing E_ERROR conditions have been 56 | converted to something that can be caught with a user-defined error 57 | handler. If an E_RECOVERABLE_ERROR 58 | is not handled, it will behave in the same way as 59 | E_ERROR behaves in all versions of PHP. Errors of 60 | this type are logged as Catchable fatal error. 61 |

62 |

63 | This change means that the value of the E_ALL 64 | error_reporting constant is 65 | now 6143, where the previous value was 2047. Because PHP constants have 66 | no meaning outside of PHP, in some cases the integer value is used 67 | instead so these will need to be adjusted. So for example by 68 | setting the error_reporting mode from either the 69 | httpd.conf or the 70 | .htaccess files, the value has to be changed 71 | accordingly. The same applies when the numeric values are used 72 | rather than the constants in PHP scripts. 73 |

74 |

75 | As a side-effect of a change made to prevent duplicate error messages when 76 | track_errors is 77 | On, it is now necessary to return FALSE from 78 | user defined error handlers in order to populate 79 | $php_errormsg. This 80 | provides a fine-grain control over the levels of messages stored. 81 |

82 |
83 |
84 | 85 | -------------------------------------------------------------------------------- /html/extensions-other.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Other changes to extensions in PHP 5.5, 5.4, 5.3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.5

50 |
51 | 52 |
53 |

Other changes to extensions

54 | 55 |
56 |

Intl

57 | 58 |

59 | The intl extension now requires ICU 4.0 60 | or later. 61 |

62 |
63 |
64 |
65 |

PHP 5.4

66 |
67 | 68 |
69 |

Other changes to extensions

70 |

71 | Changes in extension behavior, and new features: 72 |

73 |
  • 80 | 81 | pdo_mysql 82 | - Removed support for linking with MySQL client libraries older than 4.1 83 | 84 |
  • 85 |
  • 86 | 87 | The MySQL extensions mysql, 88 | mysqli and PDO_mysql 89 | use mysqlnd as the default library now. It is still possible to use 90 | libmysqlclient by specifying a path to the configure options. 91 | 92 |
  • 93 |
  • 94 | 95 | mysqlnd 96 | - Added named pipes support 97 | 98 |
  • 99 |
100 |
101 |

PHP 5.3

102 |
103 | 104 |
105 |

Other changes to extensions

106 |

107 | The following extensions can no longer be disabled during build 108 | configuration: 109 |

110 |
  • 111 | 112 | PCRE 113 | 114 |
  • 115 |
  • 116 | 117 | Reflection 118 | 119 |
  • 120 |
  • 121 | 122 | SPL 123 | 124 |
  • 125 |

126 | Changes in extension behaviour, and new features: 127 |

128 |
  • 129 | 130 | Date and Time 131 | - The TZ environment variable is no longer used to guess the timezone 132 | 133 |
  • 134 |
  • 135 | 136 | cURL 137 | - cURL now supports SSH 138 | 139 |
  • 140 |
  • 141 | 142 | Network 143 | - dns_check_record() now returns an extra "entries" 144 | index, containing the TXT elements. 145 | 146 |
  • 147 |
  • 148 | 149 | Hash 150 | - The SHA-224 and salsa hash algorithms are now supported. 151 | 152 |
  • 153 |
  • 154 | 155 | mbstring 156 | - Now supports CP850 encoding. 157 | 158 |
  • 159 |
  • 160 | 161 | OCI8 162 | - A call to oci_close() on a persistent connection, or a 163 | variable referencing a persistent connection going out of scope, will now 164 | roll back any uncommitted transaction. To avoid unexpected behavior, 165 | explicitly issue a commit or roll back as needed. The old behavior can be 166 | enabled with the INI directive 167 | oci8.old_oci_close_semantics. 168 | 169 | 170 | Database Resident Connection Pooling (DRCP) and Fast Application 171 | Notification (FAN) are now supported. 172 | 173 | 174 | Oracle External Authentication is now supported (except on Windows). 175 | 176 | 177 | The oci_bind_by_name() function now supports SQLT_AFC 178 | (aka the CHAR datatype). 179 | 180 |
  • 181 |
  • 182 | 183 | OpenSSL 184 | - OpenSSL digest and cipher functions are now supported. It is also 185 | now possible to access the internal values of DSA, RSA and DH keys. 186 | 187 |
  • 188 |
  • 189 | 190 | Session 191 | - Sessions will no longer store session-files in "/tmp" 192 | when open_basedir restrictions 193 | apply, unless "/tmp" is explicitly added to the list of 194 | allowed paths. 195 | 196 |
  • 197 |
  • 198 | 199 | SOAP 200 | Now supports sending user supplied HTTP headers. 201 | 202 |
  • 203 |
  • 204 | 205 | MySQLi 206 | Now supports persistent connections, by prepending the hostname with 207 | "p:". 208 | 209 |
  • 210 |
  • 211 | 212 | Image Processing and GD 213 | The "JPG Support" index returned from gd_info() has 214 | been renamed to "JPEG Support". 215 | 216 |
  • 217 | 218 | 219 |
220 |
221 | 222 | -------------------------------------------------------------------------------- /html/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eusonlito/php-changes-cheatsheet/5e9797c6212011e5c067cf9f2cf40698c05a2c85/html/favicon-16x16.png -------------------------------------------------------------------------------- /html/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eusonlito/php-changes-cheatsheet/5e9797c6212011e5c067cf9f2cf40698c05a2c85/html/favicon-32x32.png -------------------------------------------------------------------------------- /html/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eusonlito/php-changes-cheatsheet/5e9797c6212011e5c067cf9f2cf40698c05a2c85/html/favicon-96x96.png -------------------------------------------------------------------------------- /html/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eusonlito/php-changes-cheatsheet/5e9797c6212011e5c067cf9f2cf40698c05a2c85/html/favicon.ico -------------------------------------------------------------------------------- /html/images/bg-texture-00.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /html/images/mobile-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eusonlito/php-changes-cheatsheet/5e9797c6212011e5c067cf9f2cf40698c05a2c85/html/images/mobile-menu.png -------------------------------------------------------------------------------- /html/images/search-sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eusonlito/php-changes-cheatsheet/5e9797c6212011e5c067cf9f2cf40698c05a2c85/html/images/search-sprites.png -------------------------------------------------------------------------------- /html/images/social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eusonlito/php-changes-cheatsheet/5e9797c6212011e5c067cf9f2cf40698c05a2c85/html/images/social.png -------------------------------------------------------------------------------- /html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PHP changes cheatsheet 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 44 | 45 |
46 | 253 |
254 | 255 | -------------------------------------------------------------------------------- /html/integer-parameters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Integer values in function parameters in PHP 5.1 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.1

50 |
51 | 52 |
53 |

Integer values in function parameters

54 |

55 | With the advent of PHP 5.0.x, a new parameter parsing API was introduced 56 | which is used by a large number of PHP functions. In all versions of PHP 57 | between 5.0.x and 5.1.x, the handling of integer values was very strict and 58 | would reject non-well formed numeric values when a PHP function expected an 59 | integer. These checks have now been relaxed to support non-well formed 60 | numeric strings such as " 123" and "123 ", and will no longer fail as they 61 | did under PHP 5.0.x. However, to promote code safety and input validation, 62 | PHP functions will now emit an E_NOTICE when such 63 | strings are passed as integers. 64 |

65 |
66 |
67 | 68 | -------------------------------------------------------------------------------- /html/internals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Changes to PHP Internals in PHP 5.5 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.5

50 |
51 | 52 |
53 |

Changes to PHP Internals

54 | 55 |
  • 56 | 57 | Extensions cannot override zend_execute() any more and 58 | should override zend_execute_ex() instead. 59 | EG(current_execute_data) is already initialized in 60 | zend_execute_ex(), so for compatibility extensions may 61 | need to use 62 | EG(current_execute_data)->prev_execute_data instead. 63 | 64 |
  • 65 |
  • 66 | 67 | Removed EG(arg_types_stack), 68 | EX(fbc), EX(called_scope) and 69 | EX(current_object). 70 | 71 |
  • 72 |
  • 73 | 74 | Added op_array->nested_calls, which is calculated 75 | at compile time. 76 | 77 |
  • 78 |
  • 79 | 80 | Added EX(call_slots), which is an array to store 81 | information about syntaticaly nested calls (e.g. 82 | foo(bar())) and is preallocated together with 83 | execute_data. 84 | 85 |
  • 86 |
  • 87 | 88 | Added EX(call), which is a pointer to a current 89 | calling function, and is an element of EX(call_slots). 90 | 91 |
  • 92 |
  • 93 | 94 | Opcodes 95 | INIT_METHOD_CALL, 96 | ZEND_INIT_STATIC_METHOD_CALL, 97 | ZEND_INIT_FCALL_BY_NAME 98 | and 99 | ZEND_INIT_NS_FCALL_BY_NAME 100 | use result.num as an index in 101 | EX(call_slots). 102 | 103 |
  • 104 |
  • 105 | 106 | Opcode ZEND_NEW uses 107 | extended_value as an index in 108 | EX(call_slots). 109 | 110 |
  • 111 |
  • 112 | 113 | Opcodes ZEND_DO_FCALL 114 | and 115 | ZEND_DO_FCALL_BY_NAME 116 | use op2.num as an index in 117 | EX(call_slots). 118 | 119 |
  • 120 |
  • 121 | 122 | Added op_array->used_stack, which is calculated at 123 | compile time; the corresponding stack space is preallocated together with 124 | execute_data. As a result, the ZEND_SEND* and 125 | ZEND_DO_FCALL* opcodes no longer need to check for stack overflow. 126 | 127 |
  • 128 |
  • 129 | 130 | Removed execute_data->Ts field. The VM temporary 131 | variables are always allocated immediately before the 132 | execute_data structure, and are now accessed by their 133 | offset from the execute_data base pointer instead of 134 | via execute_data->Ts. The compiler stores new 135 | offsets in op_array->opcodes[*].op?.num. The 136 | EX_TMP_VAR() and EX_TMP_VAR_NUM() 137 | macros can be used to access temporary variables by offset or number. You 138 | can convert the number to an offset using EX_TMP_VAR_NUM(0, 139 | num) or offset to number using 140 | (EX_TMP_VAR_NUM(0,0)-EX_TMP_VAR(0,offset)). 141 | 142 |
  • 143 |
  • 144 | 145 | Removed the execute_data->CVs field. The VM 146 | compiled variables are always allocated immediately after the 147 | execute_data structure, and are now accessed by the 148 | offset from the execute_data base pointer instead of 149 | via execute_data->CVs. You can use the 150 | EX_CV_NUM() macro to access compiled variables by 151 | number. 152 | 153 |
  • 154 |
155 |
156 | 157 | -------------------------------------------------------------------------------- /html/newconf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | New INI Configuration Directives in PHP 5.2, 5.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.2

50 |
51 | 52 |
53 |

New INI Configuration Directives

54 |

55 | New php.ini directives introduced in PHP 5.2.0: 56 |

57 |
  • 58 | 59 | allow_url_include 60 | 61 | 62 | This useful option makes it possible to differentiate between 63 | standard file operations on remote files, and the inclusion of 64 | remote files. While the former is usually desirable, the latter can 65 | be a security risk if used naively. Starting with PHP 5.2.0, you can 66 | allow remote file operations while disallowing the inclusion of 67 | remote files in local scripts. In fact, this is the default 68 | configuration. 69 | 70 |
  • 71 |
  • 72 | 73 | pcre.backtrack_limit 74 | 75 | 76 | PCRE's backtracking limit. 77 | 78 |
  • 79 |
  • 80 | 81 | pcre.recursion_limit 82 | 83 | 84 | PCRE's recursion limit. Please note that if you set this value to a high 85 | number you may consume all the available process stack and eventually 86 | crash PHP (due to reaching the stack size limit imposed by the Operating 87 | System). 88 | 89 |
  • 90 |
  • 91 | 92 | session.cookie_httponly 93 | 94 | 95 | Marks the cookie as accessible only through the HTTP protocol. This means 96 | that the cookie won't be accessible by scripting languages, such as 97 | JavaScript. This setting can effectively help to reduce identity theft 98 | through XSS attacks (although it is not supported by all browsers). 99 | 100 |
  • 101 |

102 | New directives in PHP 5.2.2: 103 |

104 |
114 |
115 |

PHP 5.0

116 |
117 | 118 |
119 |

New Directives

120 |

121 | There were some new php.ini directives introduced in PHP 5. Here is a 122 | list of them: 123 |

124 |
  • 125 | 126 | mail.force_extra_parameters - 127 | Force the addition of the specified 128 | parameters to be passed as extra parameters to the sendmail binary. 129 | These parameters will always replace the value of the 5th parameter to 130 | mail(), even in safe mode 131 | 132 |
  • 133 |
  • 134 | 135 | register_long_arrays - 136 | allow/disallow PHP to register the deprecated long $HTTP_*_VARS 137 | 138 |
  • 139 |
  • 140 | 141 | session.hash_function - 142 | select a hash function (MD5 or SHA-1) 143 | 144 |
  • 145 |
  • 146 | 147 | session.hash_bits_per_character 148 | - define how many bits are stored in each character when converting the 149 | binary hash data to something readable (from 4 to 6) 150 | 151 |
  • 152 |
  • 153 | 154 | zend.ze1_compatibility_mode 155 | - Enable compatibility mode with Zend Engine 1 (PHP 4) 156 | 157 |
  • 158 |
159 |
160 | 161 | -------------------------------------------------------------------------------- /html/oop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Class and object changes in PHP 5.1, 5.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.1

50 |
51 | 52 |
53 |

Class and object changes

54 |
84 |

instanceof, is_a(), 85 | is_subclass_of() and catch

86 |

87 | In PHP 5.0, is_a() was deprecated and replaced by the 88 | instanceof operator. There were some issues with the 89 | initial implementation of instanceof, which relied on 90 | __autoload() to search for missing classes. 91 | If the class was not present, instanceof would throw 92 | a fatal E_ERROR due to the failure of 93 | __autoload() to discover that class. The same behaviour 94 | occurred in the catch operator and the 95 | is_subclass_of() function, for the same reason. 96 |

97 |

98 | None of these functions or operators call __autoload() 99 | in PHP 5.1.x, and the class_exists() workarounds used 100 | in code written for PHP 5.0.x, while not problematic in any way, are no 101 | longer necessary. 102 |

103 |
104 | 105 |
106 |

Abstract private methods

107 |

108 | Abstract private methods were supported between PHP 5.0.0 and PHP 5.0.4, 109 | but were then disallowed on the grounds that the behaviours of 110 | private and abstract are mutually 111 | exclusive. 112 |

113 |
114 | 115 |
116 |

Access modifiers in interfaces

117 |

118 | Under PHP 5.0, function declarations in interfaces were treated in exactly 119 | the same way as function declarations in classes. This has not been the 120 | case since October 2004, at which point only the public 121 | access modifier was allowed in interface function declarations. Since 122 | April 2005 - which pre-dates the PHP 5.0b1 release - the 123 | static modifier has also been allowed. However, the 124 | protected and private modifiers will 125 | now throw an E_ERROR, as will 126 | abstract. Note that this change should not affect your 127 | existing code, as none of these modifiers makes sense in the context of 128 | interfaces anyway. 129 |

130 |
131 | 132 |
133 |

Changes in inheritance rules

134 |

135 | Under PHP 5.0, it was possible to have a function declaration in a derived 136 | class that did not match the declaration of the same function in the base 137 | class, e.g. 138 |

139 |
140 |

141 | This code will cause an E_STRICT error to be emitted 142 | under PHP 5.1.x. 143 |

144 |
145 |
146 | class Base {
    function &
return_by_ref() {
        
$r 1;
        return 
$r;
    }
}

class 
Derived extends Base {
    function 
return_by_ref() {
        return 
1;
    }
}
?> 147 |
148 |
149 |
150 | 151 |
152 |
153 | 154 |
155 |

Class constants

156 |

157 | Under PHP 5.0.x, the following code was valid: 158 |

159 |
160 |

161 | Under PHP 5.1.x, redefinition of a class constant will throw a fatal 162 | E_ERROR. 163 |

164 |
165 |
166 | class test {
    const 
foobar 'foo';
    const 
foobar 'bar';
}

?> 167 |
168 |
169 |
170 | 171 |
172 |
173 |
174 |
175 |

PHP 5.0

176 |
177 | 178 |
179 |

New Object Model

180 |

181 | In PHP 5 there is a new Object Model. PHP's handling of objects has been 182 | completely rewritten, allowing for better performance and more features. 183 | In previous versions of PHP, objects were handled like primitive types 184 | (for instance integers and strings). The drawback of this method was that 185 | semantically the whole object was copied when a variable was assigned, or 186 | passed as a parameter to a method. In the new approach, objects are 187 | referenced by handle, and not by value (one can think of a handle as an 188 | object's identifier). 189 |

190 |

191 | Many PHP programmers aren't even aware of the copying quirks of the old 192 | object model and, therefore, the majority of PHP applications will work 193 | out of the box, or with very few modifications. 194 |

195 |

196 | The new Object Model is documented at the Language Reference. 197 |

198 |

199 | In PHP 5, function with the name of a class is called as a constructor 200 | only if defined in the same class. In PHP 4, it is called also if defined 201 | in the parent class. 202 |

203 |

204 | See also the 205 | zend.ze1_compatibility_mode directive for compatibility with 206 | PHP 4. 207 |

208 |
209 |
210 | 211 | -------------------------------------------------------------------------------- /html/reading.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Reading [] in PHP 5.1 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.1

50 |
51 | 52 |
53 |

Reading []

54 |
55 |
56 |
57 | class XmlTest {

    function 
test_ref(&$test) {
        
$test "ok";
    }

    function 
test($test) { }

    function 
run() {
        
$ar = array();
        
$this->test_ref($ar[]);
        
var_dump($ar);
        
$this->test($ar[]);
    }
}

$o = new XmlTest();
$o->run();
?> 58 |
59 |
60 |
61 | 62 |
63 |

64 | This should always have thrown a fatal E_ERROR, 65 | because [] cannot be used for reading in PHP. It is invalid code in 66 | PHP 4.4.2 and PHP 5.0.5 upward. 67 |

68 |
69 |
70 | 71 | -------------------------------------------------------------------------------- /html/removed-extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Removed Extensions in PHP 8.4, 7.4, 5.4, 5.3, 5.2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 8.4

50 |
51 | 52 |
53 |

Removed Extensions

54 | 55 |

56 | These extensions have been moved to PECL and are no longer part of the PHP 57 | distribution. New releases for the PECL packages will be published on an 58 | ad-hoc basis according to user demand. 59 |

60 | 61 |
66 |
67 |

PHP 7.4

68 |
69 | 70 |
71 |

Removed Extensions

72 | 73 |

74 | These extensions have been moved to PECL and are no longer part of the PHP 75 | distribution. The PECL package versions of these extensions will be created 76 | according to user demand. 77 |

78 | 79 |
  • 80 | 81 | Firebird/Interbase 82 | - access to an InterBase and/or Firebird based database is still 83 | available with the PDO Firebird driver. 84 | 85 |
  • 86 |
  • 87 | 88 | Recode 89 | 90 |
  • 91 |
  • 92 | 93 | WDDX 94 | 95 |
  • 96 |
97 |
98 |

PHP 5.4

99 |
100 | 101 |
102 |

Removed Extensions

103 |

104 | These extensions have been moved to PECL and are no longer part of the PHP 105 | distribution. The PECL package versions of these extensions will be created 106 | according to user demand. 107 |

108 |
  • 109 | 110 | sqlite 111 | - Note that ext/sqlite3 and ext/pdo_sqlite are not affected 112 | 113 |
  • 114 |
115 |
116 |

PHP 5.3

117 |
118 | 119 |
120 |

Removed Extensions

121 |

122 | These extensions have been moved to PECL and are no longer part of the PHP 123 | distribution. The PECL package versions of these extensions will be created 124 | according to user demand. 125 |

126 |
  • 127 | 128 | dbase 129 | - No longer maintained 130 | 131 |
  • 132 |
  • 133 | 134 | fbsql 135 | - No longer maintained 136 | 137 |
  • 138 |
  • 139 | 140 | fdf 141 | - Maintained 142 | 143 |
  • 144 |
  • 145 | 146 | ming 147 | - Maintained 148 | 149 |
  • 150 |
  • 151 | 152 | msql 153 | - No longer maintained 154 | 155 |
  • 156 |
  • 157 | 158 | ncurses 159 | - Maintained 160 | 161 |
  • 162 |
  • 163 | 164 | sybase 165 | - Discontinued; use the sybase_ct 166 | extension instead 167 | 168 |
  • 169 |
  • 170 | 171 | mhash 172 | - Discontinued; use the hash extension 173 | instead. hash has full mhash 174 | compatibility; all existing applications using the old functions will 175 | continue to work. 176 | 177 |
  • 178 |
179 |
180 |

PHP 5.2

181 |
182 | 183 |
184 |

Removed Extensions

185 |

186 | These extensions have been moved to PECL and are no longer 187 | part of the PHP distribution. The PECL package version of 188 | these extensions will be created according to user demand. 189 |

190 |
201 |
202 | 203 | -------------------------------------------------------------------------------- /html/removed-exts-sapis.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Removed Extensions and SAPIs in PHP 7.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 7.0

50 |
51 | 52 |
53 |

Removed Extensions and SAPIs

54 | 55 |
56 |

Removed Extensions

57 | 58 |
  • 59 | 60 | ereg 61 | 62 |
  • 63 |
  • 64 | 65 | mssql 66 | 67 |
  • 68 |
  • 69 | 70 | mysql 71 | 72 |
  • 73 |
  • 74 | 75 | sybase_ct 76 | 77 |
  • 78 |
79 | 80 |
81 |

Removed SAPIs

82 | 83 |
  • 84 | 85 | aolserver 86 | 87 |
  • 88 |
  • 89 | 90 | apache 91 | 92 |
  • 93 |
  • 94 | 95 | apache_hooks 96 | 97 |
  • 98 |
  • 99 | 100 | apache2filter 101 | 102 |
  • 103 |
  • 104 | 105 | caudium 106 | 107 |
  • 108 |
  • 109 | 110 | continuity 111 | 112 |
  • 113 |
  • 114 | 115 | isapi 116 | 117 |
  • 118 |
  • 119 | 120 | milter 121 | 122 |
  • 123 |
  • 124 | 125 | nsapi 126 | 127 |
  • 128 |
  • 129 | 130 | phttpd 131 | 132 |
  • 133 |
  • 134 | 135 | pi3web 136 | 137 |
  • 138 |
  • 139 | 140 | roxen 141 | 142 |
  • 143 |
  • 144 | 145 | thttpd 146 | 147 |
  • 148 |
  • 149 | 150 | tux 151 | 152 |
  • 153 |
  • 154 | 155 | webjames 156 | 157 |
  • 158 |
159 |
160 |
161 | 162 | -------------------------------------------------------------------------------- /html/sapi-changes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Changes in SAPI Modules in PHP 7.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 7.0

50 |
51 | 52 |
53 |

Changes in SAPI Modules

54 | 55 |
56 |

FPM

57 | 58 |
59 |

60 | Unqualified listen ports now listen on both 61 | IPv4 and IPv6 62 |

63 | 64 |

65 | In PHP 5, a listen directive with only a 66 | port number would listen on all interfaces, but only on IPv4. PHP 7 will 67 | now accept requests made via both IPv4 and IPv6. 68 |

69 | 70 |

71 | This does not affect directives which include specific IP addresses; these 72 | will continue to only listen on that address and protocol. 73 |

74 |
75 |
76 |
77 |
78 | 79 | -------------------------------------------------------------------------------- /html/sapi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Changes in SAPI modules in PHP 5.4, 5.3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.4

50 |
51 | 52 |
53 |

Changes in SAPI modules

54 |
  • 55 | 56 | A new SAPI module named cli-server is now available. 57 | 58 |
  • 59 |
  • 60 | 61 | Added CLI option --rz which shows information of the named Zend extension. 62 | 63 |
  • 64 |
  • 65 | 66 | Added shortcut #inisetting=value to change php.ini settings at run-time in interactive readline CLI 67 | 68 |
  • 69 |
  • 70 | 71 | Added apache compatible functions: apache_child_terminate(), 72 | getallheaders(), apache_request_headers() 73 | and apache_response_headers() for FastCGI SAPI. 74 | 75 |
  • 76 |
  • 77 | 78 | PHP-FPM: Added the process.max setting, to control the number 79 | of processes that FPM can fork. 80 | 81 |
  • 82 |
83 |
84 |

PHP 5.3

85 |
86 | 87 |
88 |

Changes in SAPI modules

89 |
  • 90 | 91 | A new SAPI module named litespeed is now available. 92 | 93 |
  • 94 |
  • 95 | 96 | FastCGI support in the CGI SAPI is now always enabled and can not be 97 | disabled. See sapi/cgi/CHANGES for more details. 98 | 99 |
  • 100 |
  • 101 | 102 | A new CGI SAPI option, -T, can be used to measure 103 | repeated execution time of a script. 104 | 105 |
  • 106 |
  • 107 | 108 | CGI/FastCGI now has support for .htaccess-style user-defined php.ini 109 | files. 110 | 111 |
  • 112 |
  • 113 | 114 | The dl() function is now disabled by default, and is now 115 | available only under the CLI, CGI, and embed SAPIs. 116 | 117 |
  • 118 |
119 |
120 | 121 | -------------------------------------------------------------------------------- /html/stream-filters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | New stream filters in PHP 5.3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.3

50 |
51 | 52 |
53 |

New stream filters

54 |

55 | The following stream filters were introduced in 5.3.0: 56 |

57 |
  • 58 | 59 | dechunk (reverses HTTP chunked encoding) 60 | 61 |
  • 62 |
  • 63 | 64 | The bz2.decompress filter now supports concatenation. 65 | 66 |
  • 67 |
68 |
69 | 70 | -------------------------------------------------------------------------------- /html/stream-wrappers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | New stream wrappers in PHP 5.3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.3

50 |
51 | 52 |
53 |

New stream wrappers

54 |

55 | The following stream wrappers were introduced in 5.3.0: 56 |

57 |
68 |
69 | 70 | -------------------------------------------------------------------------------- /html/styles.css: -------------------------------------------------------------------------------- 1 | /* Variables */ 2 | :root { 3 | --black: #1B1B1B; 4 | --gutter: 20px; 5 | } 6 | 7 | *, *::before, *::after { 8 | box-sizing: border-box; 9 | } 10 | 11 | body { 12 | font-family: 'Source Sans Pro', Helvetica, sans-serif; 13 | margin: 0; 14 | color: #333; 15 | background: #333; 16 | } 17 | 18 | header.title, h1:after, h2:after, h3:after { 19 | display: table; 20 | width: 100%; 21 | content: ""; 22 | margin-top: 0; 23 | border-bottom: none; 24 | } 25 | 26 | .navbar { 27 | padding: 10px 20px; 28 | } 29 | 30 | .navbar h1 { 31 | color: white; 32 | text-align: center; 33 | margin: 0; 34 | white-space: nowrap; 35 | overflow: scroll; 36 | scrollbar-width: none; 37 | -ms-overflow-style: none; 38 | } 39 | 40 | .navbar h1::-webkit-scrollbar { 41 | display: none; 42 | } 43 | 44 | .navbar h1 a { 45 | color: white; 46 | text-shadow: none; 47 | font-weight: normal; 48 | } 49 | 50 | .navbar h1 a:before { 51 | content: "\20 \00AB"; 52 | } 53 | 54 | .navbar h1 a:hover::before { 55 | text-decoration: underline; 56 | } 57 | 58 | /* Main content */ 59 | .main-content { 60 | padding: 0; 61 | display: grid; 62 | grid-auto-columns: minmax(max-content, 1fr); 63 | } 64 | 65 | .main-content article { 66 | grid-row: 1; 67 | margin-right: 1px; 68 | margin-bottom: 1px; 69 | padding-bottom: 1rem; 70 | background: var(--color); 71 | color: var(--black); 72 | } 73 | 74 | .main-content h1 { 75 | font-size: .9em; 76 | margin: 0; 77 | padding: .5rem 1rem; 78 | text-transform: uppercase; 79 | background-color: #0002; 80 | } 81 | 82 | .main-content a { 83 | color: inherit; 84 | } 85 | 86 | .main-content a:hover { 87 | background: var(--black); 88 | color: var(--color); 89 | } 90 | 91 | .main-content h2 { 92 | font-size: 0.9rem; 93 | line-height: 1em; 94 | padding: .5rem 1rem; 95 | margin: 1rem 0 0; 96 | } 97 | 98 | .main-content ul { 99 | font-size: 0.8rem; 100 | line-height: 1em; 101 | list-style: none; 102 | margin: 0; 103 | padding: 0; 104 | } 105 | 106 | .main-content ul li a { 107 | text-decoration: none; 108 | display: block; 109 | padding: .25rem 1rem; 110 | } 111 | 112 | .info-main { 113 | background: #333; 114 | display: grid; 115 | grid-auto-columns: 48%; 116 | grid-auto-flow: column; 117 | grid-column-gap: 20px; 118 | padding: 20px; 119 | 120 | overflow-x: auto; 121 | scroll-snap-type: x proximity; 122 | } 123 | 124 | .index-main { 125 | padding: 20px; 126 | margin: 0 auto; 127 | } 128 | 129 | .index-main ul { 130 | margin: 0; 131 | } 132 | 133 | .index-main ul li a { 134 | display: block; 135 | background: #F2F2F2; 136 | padding: 7px 15px; 137 | margin-bottom: 5px; 138 | color: #000; 139 | border: 0; 140 | transition: 0.15s all ease; 141 | } 142 | 143 | .index-main ul li a:hover { 144 | padding: 7px 20px; 145 | background: #FFF; 146 | } 147 | 148 | .index-main ul li a .versions { 149 | float: right; 150 | } 151 | 152 | .index-main ul li a .versions span { 153 | display: inline-block; 154 | margin-right: 5px; 155 | font-size: 0.75rem; 156 | line-height: 1.2rem; 157 | padding: 0 5px; 158 | background: #8892BF; 159 | color: #F2F2F2; 160 | border-radius: 20%; 161 | font-weight: 600; 162 | } 163 | 164 | .info-wrapper + .info-wrapper { 165 | padding-top: 20px; 166 | } 167 | 168 | .info-main { 169 | font-family: "Fira Sans", "Source Sans Pro", Helvetica, Arial, sans-serif; 170 | } 171 | 172 | .info-main .info-version { 173 | background: #F2F2F2; 174 | padding: 20px; 175 | overflow: auto; 176 | min-height: 86.7vh; 177 | max-height: 86.7vh; 178 | } 179 | 180 | .info-main .title, 181 | .info-main .title a { 182 | color: #793862; 183 | } 184 | 185 | .info-main header.title, 186 | .info-main h2:after, 187 | .info-main h3:after { 188 | display: table; 189 | width: 100%; 190 | content: " "; 191 | margin-top: -1px; 192 | border-bottom: 1px dotted; 193 | } 194 | 195 | .info-main h1:after { 196 | border-bottom: none; 197 | } 198 | 199 | .info-main a:link, 200 | .info-main a:visited { 201 | color: #369; 202 | } 203 | 204 | .info-main h1 a, 205 | .info-main h2 a, 206 | .info-main h3 a { 207 | display: block; 208 | } 209 | 210 | #intro .blurb, #layout-content { 211 | float: none !important; 212 | width: auto !important; 213 | } 214 | 215 | @media (min-width: 768px) { 216 | .main-content ul.ly-horizontal { 217 | flex-wrap: nowrap; 218 | } 219 | 220 | .index-main { 221 | max-width: 70%; 222 | } 223 | } 224 | 225 | @media (min-width: 1240px) { 226 | .index-main { 227 | max-width: 55%; 228 | } 229 | } 230 | 231 | @media (max-width: 767px) { 232 | .info-main { 233 | grid-auto-columns: 98%; 234 | } 235 | 236 | .info-main .info-version { 237 | padding: 10px; 238 | } 239 | } 240 | 241 | @media (max-width: 967px) { 242 | .index-main ul li a .versions span { 243 | display: none; 244 | } 245 | } -------------------------------------------------------------------------------- /html/undeprecated.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Undeprecated features in PHP 5.3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.3

50 |
51 | 52 |
53 |

Undeprecated features in PHP 5.3.x

54 |

55 | The is_a() function has been undeprecated by popular 56 | request; it will no longer issue an E_STRICT error. 57 |

58 |
59 |
60 | 61 | -------------------------------------------------------------------------------- /html/windows.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Changes made to Windows support in PHP 5.3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 |
48 |
49 |

PHP 5.3

50 |
51 | 52 |
53 |

Changes made to Windows support

54 |

55 | Changes to the Windows releases: 56 |

57 |
  • 58 | 59 | The minimum Windows version is now Windows XP SP3; Windows 98, ME, 2000 and NT4 60 | are no longer supported. 61 | 62 |
  • 63 |
  • 64 | 65 | Windows binaries now target i586 and later. i386 and i486 are not 66 | supported. 67 | 68 |
  • 69 |
  • 70 | 71 | There is now experimental support for x64 versions of PHP on Windows. 72 | 73 |
  • 74 |
  • 75 | 76 | There is now compiler support for Visual C++ 9 (VC9), using Visual Studio 77 | 2008. Snapshots and releases will now also be available for VC9. Old 78 | binaries using VC6 are still supported and released in the line with VC9. 79 | 80 |
  • 81 |
  • 82 | 83 | The PDO_OCI 84 | php_pdo_oci8.dll library (for use with Oracle version 8 85 | client libraries) is no longer being built. Instead, use 86 | php_pdo_oci.dll (note no '8') with Oracle 10 or 11 87 | client libraries. Connection to other database versions is still supported. 88 | 89 |
  • 90 |
  • 91 | 92 | For the OCI8 extension, a new library 93 | php_oci8_11g.dll is available in addition to 94 | php_oci8.dll. Only one can be enabled at any time. Use 95 | php_oci8.dll with Oracle 10.2 client libraries. Use 96 | php_oci8_11g.dll with Oracle 11 or later client libraries. 97 | Connection to other database versions is still supported. 98 | 99 |
  • 100 |

101 | Windows support has been added for the following functions: 102 |

103 |

191 | Other changes: 192 |

193 |
  • 194 | 195 | Improved portability of the stat(), 196 | touch(), filemtime(), 197 | filesize() functions, and other related functions (100% 198 | portable for the available data). 199 | 200 |
  • 201 |
  • 202 | 203 | It is now possible to create hard links on Windows using the 204 | link() function, and symbolic links using the 205 | symlink() function. Hard links are available as of 206 | Windows 2000, and symbolic links as of Windows Vista. 207 | 208 |
  • 209 |
  • 210 | 211 | The Windows version of PHP now exposes a set of constants prefixed 212 | PHP_WINDOWS_*. A list of these constants and their usage 213 | can be found at Predefined Constants. 214 | 215 |
  • 216 |
Warning 217 |

218 | Support for the ISAPI module has been dropped. Use the improved FastCGI SAPI 219 | module instead. 220 |

221 |
222 |

Note: 223 | 224 | A new dedicated site for PHP on Windows is now available, including 225 | downloads, release candidates, and snapshots in various flavors 226 | (thread-safe/not-thread-safe, VC6/VC9, x86/x64). The URL of this site is 227 | » https://windows.php.net/. 228 | 229 |

230 |
231 |
232 | 233 | -------------------------------------------------------------------------------- /src/Command/All.php: -------------------------------------------------------------------------------- 1 | command('Cache'); 13 | $this->command('Chunk'); 14 | $this->command('Html'); 15 | $this->command('Asset'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Command/Asset.php: -------------------------------------------------------------------------------- 1 | command('AssetCss'); 15 | $this->command('AssetFavicon'); 16 | $this->command('AssetImages'); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Command/AssetCss.php: -------------------------------------------------------------------------------- 1 | remote(); 15 | $this->local(); 16 | $this->images(); 17 | } 18 | 19 | /** 20 | * @param string $theme 21 | * 22 | * @return string 23 | */ 24 | protected function url(string $theme): string 25 | { 26 | return static::URL_BASE.'/cached.php?f=/styles/theme-'.$theme.'.css&t='.time(); 27 | } 28 | 29 | /** 30 | * @param string $file 31 | * 32 | * @return string 33 | */ 34 | protected function path(string $file): string 35 | { 36 | return static::PATH_HTML.'/'.$file; 37 | } 38 | 39 | /** 40 | * @param string $file 41 | * 42 | * @return string 43 | */ 44 | protected function asset(string $file): string 45 | { 46 | return PATH_SRC.'/views/assets/'.$file; 47 | } 48 | 49 | /** 50 | * @return void 51 | */ 52 | protected function remote(): void 53 | { 54 | $target = $this->path('phpnet.css'); 55 | $css = $this->remoteFix($this->remoteContents()); 56 | 57 | MessageConsole::echo(sprintf("Download CSS into %s\n", $this->removePathBase($target))); 58 | 59 | $this->fileWrite($target, $css); 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | protected function remoteContents(): string 66 | { 67 | return file_get_contents($this->url('base'))."\n".file_get_contents($this->url('medium')); 68 | } 69 | 70 | /** 71 | * @param string $css 72 | * 73 | * @return string 74 | */ 75 | protected function remoteFix(string $css): string 76 | { 77 | return preg_replace(['/url\(["\'](.*)["\']\)/', '/url\(\.*\/*/'], ['url($1)', 'url('], $css); 78 | } 79 | 80 | /** 81 | * @return void 82 | */ 83 | protected function local(): void 84 | { 85 | $target = $this->path('styles.css'); 86 | $source = $this->asset('css/styles.css'); 87 | 88 | MessageConsole::echo(sprintf("Copy %s into %s\n", $this->removePathBase($source), $this->removePathBase($target))); 89 | 90 | $this->fileWrite($target, $source, true); 91 | } 92 | 93 | /** 94 | * @return void 95 | */ 96 | protected function images(): void 97 | { 98 | if (preg_match_all('/url\(([^\)]+)/', file_get_contents($this->path('phpnet.css')), $matches) === 0) { 99 | return; 100 | } 101 | 102 | foreach ($matches[1] as $image) { 103 | $this->image($image); 104 | } 105 | } 106 | 107 | /** 108 | * @param string $image 109 | * 110 | * @return void 111 | */ 112 | protected function image(string $image): void 113 | { 114 | $image = str_replace(["'", '"', '../'], '', $image); 115 | 116 | $this->fileWrite($this->path('images/'.basename($image)), static::URL_BASE.'/'.$image, true); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Command/AssetFavicon.php: -------------------------------------------------------------------------------- 1 | files() as $file) { 16 | $this->store($file); 17 | } 18 | } 19 | 20 | /** 21 | * @param string $file = '' 22 | * 23 | * @return string 24 | */ 25 | protected function path(string $file = ''): string 26 | { 27 | return static::PATH_HTML.'/'.$file; 28 | } 29 | 30 | /** 31 | * @return array 32 | */ 33 | protected function files(): array 34 | { 35 | return DirectoryFilesystem::files(static::PATH_ASSET.'/favicon'); 36 | } 37 | 38 | /** 39 | * @param string $file 40 | * 41 | * @return void 42 | */ 43 | protected function store(string $file): void 44 | { 45 | $target = $this->storeName($file); 46 | 47 | MessageConsole::echo(sprintf("Creating %s favicon\n", $this->removePathBase($target))); 48 | 49 | $this->fileWrite($target, $file, true); 50 | } 51 | 52 | /** 53 | * @param string $file 54 | * 55 | * @return string 56 | */ 57 | protected function storeName(string $file): string 58 | { 59 | return $this->path(basename($file)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Command/AssetImages.php: -------------------------------------------------------------------------------- 1 | files() as $file) { 16 | $this->store($file); 17 | } 18 | } 19 | 20 | /** 21 | * @param string $file = '' 22 | * 23 | * @return string 24 | */ 25 | protected function path(string $file = ''): string 26 | { 27 | return static::PATH_HTML.'/images/'.$file; 28 | } 29 | 30 | /** 31 | * @return array 32 | */ 33 | protected function files(): array 34 | { 35 | return DirectoryFilesystem::files(static::PATH_ASSET.'/images'); 36 | } 37 | 38 | /** 39 | * @param string $file 40 | * 41 | * @return void 42 | */ 43 | protected function store(string $file): void 44 | { 45 | $target = $this->storeName($file); 46 | 47 | MessageConsole::echo(sprintf("Creating %s image\n", $this->removePathBase($target))); 48 | 49 | $this->fileWrite($target, $file, true); 50 | } 51 | 52 | /** 53 | * @param string $file 54 | * 55 | * @return string 56 | */ 57 | protected function storeName(string $file): string 58 | { 59 | return $this->path(basename($file)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Command/Cache.php: -------------------------------------------------------------------------------- 1 | clean(); 17 | $this->create(); 18 | 19 | foreach ($this->urls() as $url) { 20 | $this->store($url); 21 | } 22 | } 23 | 24 | /** 25 | * @return void 26 | */ 27 | protected function clean(): void 28 | { 29 | DirectoryFilesystem::rmdir($this->path()); 30 | } 31 | 32 | /** 33 | * @return void 34 | */ 35 | protected function create(): void 36 | { 37 | DirectoryFilesystem::mkdir($this->path()); 38 | } 39 | 40 | /** 41 | * @param string $file = '' 42 | * 43 | * @return string 44 | */ 45 | protected function path(string $file = ''): string 46 | { 47 | return static::PATH_CACHE_MIGRATION.'/'.$file; 48 | } 49 | 50 | /** 51 | * @param string $path 52 | * 53 | * @return string 54 | */ 55 | protected function url(string $path): string 56 | { 57 | return static::URL_DOCS.'/'.$path; 58 | } 59 | 60 | /** 61 | * @param string $path 62 | * 63 | * @return string 64 | */ 65 | protected function urlLegacy(string $path): string 66 | { 67 | return static::URL_LEGACY_DOCS.'/'.str_replace('.html', '.php', $path); 68 | } 69 | 70 | /** 71 | * @return \Generator 72 | */ 73 | protected function urls(): Generator 74 | { 75 | yield from $this->urlsCurrent(); 76 | yield from $this->urlsLegacy(); 77 | } 78 | 79 | /** 80 | * @return \Generator 81 | */ 82 | protected function urlsCurrent(): Generator 83 | { 84 | $dom = $this->dom($this->url('appendices.php')); 85 | 86 | foreach ($dom->query('//div[@id="appendices"]/ul/li/ul/li/a') as $node) { 87 | $href = $node->getAttribute('href'); 88 | 89 | if (strpos($href, 'migration') === 0) { 90 | yield $this->url($href); 91 | } 92 | } 93 | } 94 | 95 | /** 96 | * @return \Generator 97 | */ 98 | protected function urlsLegacy(): Generator 99 | { 100 | $dom = $this->dom($this->urlLegacy('appendices')); 101 | 102 | foreach ($dom->query('//div[@id="appendices"]/ul/li/ul/li/a') as $node) { 103 | $href = $node->getAttribute('href'); 104 | 105 | if (strpos($href, 'migration') === 0) { 106 | yield $this->urlLegacy($href); 107 | } 108 | } 109 | } 110 | 111 | /** 112 | * @param string $url 113 | * 114 | * @return void 115 | */ 116 | protected function store(string $url): void 117 | { 118 | $target = $this->path(basename($url)); 119 | 120 | if (is_file($target)) { 121 | MessageConsole::echo(sprintf("Skip download existing file %s into %s\n", $url, $this->removePathBase($target))); 122 | return; 123 | } 124 | 125 | MessageConsole::echo(sprintf("Downloading %s into %s\n", $url, $this->removePathBase($target))); 126 | 127 | $this->fileWrite($target, $url, true); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/Command/Chunk.php: -------------------------------------------------------------------------------- 1 | clean(); 16 | $this->create(); 17 | 18 | foreach ($this->files() as $file) { 19 | $this->store($file, $this->html($file)); 20 | } 21 | } 22 | 23 | /** 24 | * @return void 25 | */ 26 | protected function clean(): void 27 | { 28 | DirectoryFilesystem::rmdir($this->path()); 29 | } 30 | 31 | /** 32 | * @return void 33 | */ 34 | protected function create(): void 35 | { 36 | DirectoryFilesystem::mkdir($this->path()); 37 | } 38 | 39 | /** 40 | * @param string $file = '' 41 | * 42 | * @return string 43 | */ 44 | protected function path(string $file = ''): string 45 | { 46 | return static::PATH_CACHE_CHUNK.'/'.$file; 47 | } 48 | 49 | /** 50 | * @return array 51 | */ 52 | protected function files(): array 53 | { 54 | return DirectoryFilesystem::files(static::PATH_CACHE_MIGRATION); 55 | } 56 | 57 | /** 58 | * @param string $file 59 | * 60 | * @return string 61 | */ 62 | protected function html(string $file): string 63 | { 64 | $id = preg_replace('/\.php$/', '', basename($file)); 65 | $dom = $this->dom($file); 66 | 67 | return $dom->toHtml($dom->queryItem('//div[@id="'.$id.'"]')); 68 | } 69 | 70 | /** 71 | * @param string $file 72 | * @param string $html 73 | * 74 | * @return void 75 | */ 76 | protected function store(string $file, string $html): void 77 | { 78 | $target = $this->storeName($file); 79 | 80 | MessageConsole::echo(sprintf("Creating %s HTML chunk\n", $this->removePathBase($target))); 81 | 82 | $this->fileWrite($target, $html); 83 | } 84 | 85 | /** 86 | * @param string $file 87 | * 88 | * @return string 89 | */ 90 | protected function storeName(string $file): string 91 | { 92 | return $this->path(basename($file)); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Command/CommandAbstract.php: -------------------------------------------------------------------------------- 1 | clean(); 15 | $this->create(); 16 | 17 | foreach ($this->groups() as $name) { 18 | $this->group($name); 19 | } 20 | 21 | $this->index(); 22 | $this->all(); 23 | } 24 | 25 | /** 26 | * @return void 27 | */ 28 | protected function clean(): void 29 | { 30 | DirectoryFilesystem::rmdir($this->path(), '*.html'); 31 | } 32 | 33 | /** 34 | * @return void 35 | */ 36 | protected function create(): void 37 | { 38 | DirectoryFilesystem::mkdir($this->path()); 39 | } 40 | 41 | /** 42 | * @param string $file = '' 43 | * 44 | * @return string 45 | */ 46 | protected function path(string $file = ''): string 47 | { 48 | return static::PATH_HTML.'/'.$file; 49 | } 50 | 51 | /** 52 | * @return void 53 | */ 54 | protected function index(): void 55 | { 56 | $this->command('HtmlIndex'); 57 | } 58 | 59 | /** 60 | * @return void 61 | */ 62 | protected function all(): void 63 | { 64 | $this->command('HtmlAll'); 65 | } 66 | 67 | /** 68 | * @return array 69 | */ 70 | protected function groups(): array 71 | { 72 | return array_map(fn ($file) => $this->fileCode($file), DirectoryFilesystem::files(static::PATH_CACHE_CHUNK)); 73 | } 74 | 75 | /** 76 | * @param string $name 77 | * 78 | * @return void 79 | */ 80 | protected function group(string $name): void 81 | { 82 | $this->command('HtmlGroup', $name); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Command/HtmlAll.php: -------------------------------------------------------------------------------- 1 | store($this->html()); 21 | } 22 | 23 | /** 24 | * @param string $name 25 | * 26 | * @return string 27 | */ 28 | protected function name(string $name): string 29 | { 30 | return preg_replace('/[^a-z0-9-]/', '', $name); 31 | } 32 | 33 | /** 34 | * @param string $path = '' 35 | * 36 | * @return string 37 | */ 38 | protected function url(string $path = ''): string 39 | { 40 | return static::URL_DOCS.'/'.$path; 41 | } 42 | 43 | /** 44 | * @param string $file = '' 45 | * 46 | * @return string 47 | */ 48 | protected function path(string $file = ''): string 49 | { 50 | return static::PATH_HTML.'/'.$file; 51 | } 52 | 53 | /** 54 | * @return string 55 | */ 56 | protected function html(): string 57 | { 58 | $dom = $this->dom($this->path('index.html')); 59 | $html = ''; 60 | 61 | foreach ($dom->query('//main/ul/li/a') as $node) { 62 | $html .= $this->htmlNode($dom, $node); 63 | } 64 | 65 | return $this->htmlLayout($html); 66 | } 67 | 68 | /** 69 | * @param \App\Html\Dom $dom 70 | * @param \DOMElement $node 71 | * 72 | * @return string 73 | */ 74 | protected function htmlNode(DomHtml $dom, DOMElement $node): string 75 | { 76 | $link = $node->getAttribute('href'); 77 | 78 | if ((strpos($link, 'http') === 0) || ($link === 'all.html')) { 79 | return ''; 80 | } 81 | 82 | $dom = $this->dom($this->path($link)); 83 | 84 | return $dom->toHtml($dom->queryItem('//section[@class="info-wrapper"]')); 85 | } 86 | 87 | /** 88 | * @param string $html 89 | * 90 | * @return string 91 | */ 92 | protected function htmlLayout(string $html): string 93 | { 94 | return TemplateView::get('layout', [ 95 | 'class' => 'docs', 96 | 'title' => 'PHP changes cheatsheet', 97 | 'content' => $html 98 | ]); 99 | } 100 | 101 | /** 102 | * @param string $html 103 | * 104 | * @return void 105 | */ 106 | protected function store(string $html): void 107 | { 108 | $target = $this->path('all').'.html'; 109 | 110 | MessageConsole::echo(sprintf("Generating %s HTML page\n", $this->removePathBase($target))); 111 | 112 | $this->fileWrite($target, $html); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/Command/HtmlGroup.php: -------------------------------------------------------------------------------- 1 | name = $this->name($name); 34 | $this->files = $this->files(); 35 | $this->title = $this->title(); 36 | 37 | $this->store($this->html()); 38 | } 39 | 40 | /** 41 | * @param string $name 42 | * 43 | * @return string 44 | */ 45 | protected function name(string $name): string 46 | { 47 | return preg_replace('/[^a-z0-9-]/', '', $name); 48 | } 49 | 50 | /** 51 | * @param string $path = '' 52 | * 53 | * @return string 54 | */ 55 | protected function url(string $path = ''): string 56 | { 57 | return static::URL_DOCS.'/'.$path; 58 | } 59 | 60 | /** 61 | * @param string $file = '' 62 | * 63 | * @return string 64 | */ 65 | protected function path(string $file = ''): string 66 | { 67 | return static::PATH_HTML.'/'.$file; 68 | } 69 | 70 | /** 71 | * @return array 72 | */ 73 | protected function files(): array 74 | { 75 | $files = []; 76 | 77 | foreach (DirectoryFilesystem::files(static::PATH_CACHE_CHUNK) as $file) { 78 | if ($this->fileCode($file) === $this->name) { 79 | $files[$this->filesVersion($file)] = $file; 80 | } 81 | } 82 | 83 | krsort($files, SORT_NUMERIC); 84 | 85 | return $files; 86 | } 87 | 88 | /** 89 | * @param string $file 90 | * 91 | * @return string 92 | */ 93 | protected function filesVersion(string $file): string 94 | { 95 | return implode('.', str_split(preg_replace(['/[^0-9]/', '/^[0-9]$/'], ['', '${0}0'], basename($file)))); 96 | } 97 | 98 | /** 99 | * @return string 100 | */ 101 | protected function title(): string 102 | { 103 | $title = trim($this->dom(reset($this->files))->queryItem('//h2[@class="title"]')->textContent); 104 | $title = preg_replace(['/\n/', '/\s+/', '/ in PHP.*/'], [' ', ' ', ''], $title); 105 | 106 | return sprintf('%s in PHP %s', $title, implode(', ', array_keys($this->files))); 107 | } 108 | 109 | /** 110 | * @return string 111 | */ 112 | protected function html(): string 113 | { 114 | return $this->htmlLayout($this->htmlInfo($this->htmlInfoVersion($this->files))); 115 | } 116 | 117 | /** 118 | * @return string 119 | */ 120 | protected function htmlInfoVersion(): string 121 | { 122 | $html = ''; 123 | 124 | foreach ($this->files as $version => $file) { 125 | $html .= TemplateView::get('info-version', [ 126 | 'version' => $version, 127 | 'link' => $this->url(basename($file)), 128 | 'content' => $this->htmlInfoVersionContent($file) 129 | ]); 130 | } 131 | 132 | return $html; 133 | } 134 | 135 | /** 136 | * @param string $file 137 | * 138 | * @return string 139 | */ 140 | protected function htmlInfoVersionContent(string $file): string 141 | { 142 | return str_replace('href="', 'target="_blank" href="'.$this->url(), file_get_contents($file)); 143 | } 144 | 145 | /** 146 | * @param string $html 147 | * 148 | * @return string 149 | */ 150 | protected function htmlInfo(string $html): string 151 | { 152 | return TemplateView::get('info', [ 153 | 'title' => $this->title, 154 | 'versions' => array_keys($this->files), 155 | 'content' => $html 156 | ]); 157 | } 158 | 159 | /** 160 | * @param string $html 161 | * 162 | * @return string 163 | */ 164 | protected function htmlLayout(string $html): string 165 | { 166 | return TemplateView::get('layout', [ 167 | 'class' => 'docs', 168 | 'title' => $this->title, 169 | 'content' => $html 170 | ]); 171 | } 172 | 173 | /** 174 | * @param string $html 175 | * 176 | * @return void 177 | */ 178 | protected function store(string $html): void 179 | { 180 | $target = $this->path($this->name).'.html'; 181 | 182 | MessageConsole::echo(sprintf("Generating %s HTML page\n", $this->removePathBase($target))); 183 | 184 | $this->fileWrite($target, $html); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/Command/HtmlIndex.php: -------------------------------------------------------------------------------- 1 | store($this->html($this->list($this->files()))); 19 | } 20 | 21 | /** 22 | * @param string $name 23 | * 24 | * @return string 25 | */ 26 | protected function name(string $name): string 27 | { 28 | return preg_replace('/[^a-z0-9-]/', '', $name); 29 | } 30 | 31 | /** 32 | * @param string $path = '' 33 | * 34 | * @return string 35 | */ 36 | protected function url(string $path = ''): string 37 | { 38 | return static::URL_DOCS.'/'.$path; 39 | } 40 | 41 | /** 42 | * @param string $file = '' 43 | * 44 | * @return string 45 | */ 46 | protected function path(string $file = ''): string 47 | { 48 | return static::PATH_HTML.'/'.$file; 49 | } 50 | 51 | /** 52 | * @return array 53 | */ 54 | protected function files(): array 55 | { 56 | $files = []; 57 | 58 | foreach (DirectoryFilesystem::files(static::PATH_CACHE_CHUNK) as $file) { 59 | $files = $this->filesFile($files, $file); 60 | } 61 | 62 | uasort($files, static fn ($a, $b) => count($a['versions']) > count($b['versions']) ? -1 : 1); 63 | 64 | foreach ($files as &$group) { 65 | krsort($group['versions'], SORT_NUMERIC); 66 | } 67 | 68 | return $files; 69 | } 70 | 71 | /** 72 | * @param array $files 73 | * @param string $file 74 | * 75 | * @return array 76 | */ 77 | protected function filesFile(array $files, string $file): array 78 | { 79 | $name = $this->fileCode($file); 80 | 81 | if (empty($files[$name])) { 82 | $files[$name] = ['file' => $file, 'versions' => []]; 83 | } 84 | 85 | $files[$name]['versions'][] = $this->filesVersion($file); 86 | 87 | return $files; 88 | } 89 | 90 | /** 91 | * @param string $file 92 | * 93 | * @return string 94 | */ 95 | protected function filesVersion(string $file): string 96 | { 97 | return implode('.', str_split(preg_replace(['/[^0-9]/', '/^[0-9]$/'], ['', '${0}0'], basename($file)))); 98 | } 99 | 100 | /** 101 | * @param array $files 102 | * 103 | * @return array 104 | */ 105 | protected function list(array $files): array 106 | { 107 | foreach ($files as $name => $group) { 108 | $files[$name]['link'] = $this->listLink($name); 109 | $files[$name]['title'] = $this->listTitle($group); 110 | } 111 | 112 | return $files; 113 | } 114 | 115 | /** 116 | * @param string $name 117 | * 118 | * @return string 119 | */ 120 | protected function listLink(string $name): string 121 | { 122 | return $name.'.html'; 123 | } 124 | 125 | /** 126 | * @param array $group 127 | * 128 | * @return string 129 | */ 130 | protected function listTitle(array $group): string 131 | { 132 | $title = trim($this->dom(reset($group))->queryItem('//h2[@class="title"]')->textContent); 133 | $title = preg_replace(['/\n/', '/\s+/', '/ in PHP.*/'], [' ', ' ', ''], $title); 134 | 135 | return trim($title); 136 | } 137 | 138 | /** 139 | * @param array $files 140 | * 141 | * @return string 142 | */ 143 | protected function html(array $files): string 144 | { 145 | return $this->htmlLayout($this->htmlIndex($files)); 146 | } 147 | 148 | /** 149 | * @param array $files 150 | * 151 | * @return string 152 | */ 153 | protected function htmlIndex(array $files): string 154 | { 155 | return TemplateView::get('index', [ 156 | 'groups' => $files 157 | ]); 158 | } 159 | 160 | /** 161 | * @param string $html 162 | * 163 | * @return string 164 | */ 165 | protected function htmlLayout(string $html): string 166 | { 167 | return TemplateView::get('layout', [ 168 | 'class' => 'index', 169 | 'title' => 'PHP changes cheatsheet', 170 | 'content' => $html 171 | ]); 172 | } 173 | 174 | /** 175 | * @param string $html 176 | * 177 | * @return void 178 | */ 179 | protected function store(string $html): void 180 | { 181 | $target = $this->path('index').'.html'; 182 | 183 | MessageConsole::echo(sprintf("Generating %s HTML page\n", $this->removePathBase($target))); 184 | 185 | $this->fileWrite($target, $html); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/Console/Command.php: -------------------------------------------------------------------------------- 1 | Empty command\n\n")); 24 | } 25 | 26 | if (strpos($command, ',') && $arguments) { 27 | die(MessageConsole::string("\nMultiple commands and arguments are not compatible together\n\n")); 28 | } 29 | 30 | foreach (array_filter(explode(',', $command)) as $command) { 31 | static::command($command, $arguments); 32 | } 33 | } 34 | 35 | /** 36 | * @param string $command 37 | * @param array $arguments 38 | * 39 | * @return void 40 | */ 41 | protected static function command(string $command, array $arguments): void 42 | { 43 | if ($command === 'CommandAbstract') { 44 | die(MessageConsole::string("\nInvalid command\n\n")); 45 | } 46 | 47 | $class = static::getClass($command); 48 | 49 | static::classExists($class); 50 | static::print($command); 51 | static::handle($class, $arguments); 52 | 53 | echo "\n"; 54 | } 55 | 56 | /** 57 | * @param string $command 58 | * 59 | * @return string 60 | */ 61 | protected static function getClass(string $command): string 62 | { 63 | return static::NAMESPACE.'\\'.preg_replace('/[^a-zA-Z]/', '', $command); 64 | } 65 | 66 | /** 67 | * @param string $class 68 | * 69 | * @return void 70 | */ 71 | protected static function classExists(string $class): void 72 | { 73 | if (!class_exists($class)) { 74 | die(MessageConsole::string(sprintf("\nCommand %s not exists\n\n", $class))); 75 | } 76 | } 77 | 78 | /** 79 | * @param string $command 80 | * 81 | * @return void 82 | */ 83 | protected static function print(string $command): void 84 | { 85 | MessageConsole::echo(sprintf("\nExecuting command %s\n\n", $command)); 86 | } 87 | 88 | /** 89 | * @param string $command 90 | * @param array $arguments 91 | * 92 | * @return void 93 | */ 94 | protected static function handle(string $class, array $arguments): void 95 | { 96 | (new $class())->handle(...$arguments); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Console/Message.php: -------------------------------------------------------------------------------- 1 | '97', 12 | 13 | 'bold' => '1', 14 | 'dark' => '2', 15 | 'italic' => '3', 16 | 'underline' => '4', 17 | 'blink' => '5', 18 | 'reverse' => '7', 19 | 'concealed' => '8', 20 | 21 | 'default' => '39', 22 | 'black' => '30', 23 | 'red' => '31', 24 | 'green' => '32', 25 | 'yellow' => '33', 26 | 'blue' => '34', 27 | 'magenta' => '35', 28 | 'cyan' => '36', 29 | 'light_gray' => '37', 30 | 31 | 'dark_gray' => '90', 32 | 'light_red' => '91', 33 | 'light_green' => '92', 34 | 'light_yellow' => '93', 35 | 'light_blue' => '94', 36 | 'light_magenta' => '95', 37 | 'light_cyan' => '96', 38 | 'white' => '97', 39 | 40 | 'bg_default' => '49', 41 | 'bg_black' => '40', 42 | 'bg_red' => '41', 43 | 'bg_green' => '42', 44 | 'bg_yellow' => '43', 45 | 'bg_blue' => '44', 46 | 'bg_magenta' => '45', 47 | 'bg_cyan' => '46', 48 | 'bg_light_gray' => '47', 49 | 50 | 'bg_dark_gray' => '100', 51 | 'bg_light_red' => '101', 52 | 'bg_light_green' => '102', 53 | 'bg_light_yellow' => '103', 54 | 'bg_light_blue' => '104', 55 | 'bg_light_magenta' => '105', 56 | 'bg_light_cyan' => '106', 57 | 'bg_white' => '107', 58 | ]; 59 | 60 | /** 61 | * @param string $message 62 | * 63 | * @return void 64 | */ 65 | public static function echo(string $message): void 66 | { 67 | echo static::string($message); 68 | } 69 | 70 | /** 71 | * @param string $message 72 | * 73 | * @return string 74 | */ 75 | public static function string(string $message): string 76 | { 77 | return static::color('default').static::colors($message).static::color('default'); 78 | } 79 | 80 | /** 81 | * @param string $message 82 | * 83 | * @return string 84 | */ 85 | protected static function colors(string $message): string 86 | { 87 | return preg_replace_callback('/(.*)<\/color>/isU', static function ($matches) { 88 | return static::color($matches[1]).$matches[2].static::color('default'); 89 | }, $message); 90 | } 91 | 92 | /** 93 | * @param string $name 94 | * 95 | * @return string 96 | */ 97 | protected static function color(string $name): string 98 | { 99 | return "\033[".(static::COLORS[$name] ?? static::COLORS['default']).'m'; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Error/Error.php: -------------------------------------------------------------------------------- 1 | static::file($line['file']), 50 | 'line' => $line['line'] ?? '', 51 | 'function' => $line['function'] ?? '', 52 | 'class' => $line['class'] ?? '', 53 | ); 54 | } 55 | 56 | return print_r($trace, true); 57 | } 58 | 59 | /** 60 | * @param string $file 61 | * 62 | * @return string 63 | */ 64 | protected static function file(string $file): string 65 | { 66 | return str_replace(PATH_BASE, '', $file); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Error/Exception.php: -------------------------------------------------------------------------------- 1 | getCode(), $e->getMessage(), $e->getFile(), $e->getLine()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Error/Shutdown.php: -------------------------------------------------------------------------------- 1 | %s not exists', $path))); 65 | } 66 | 67 | return array_filter(glob($path.'/'.$filter), 'is_file'); 68 | } 69 | 70 | /** 71 | * @param string $path 72 | * @param array $allowed 73 | * 74 | * @return void 75 | */ 76 | protected static function isPathValid(string $path, array $allowed): void 77 | { 78 | clearstatcache(); 79 | 80 | foreach ($allowed as $folder) { 81 | if (strpos($path, $folder) === 0) { 82 | return; 83 | } 84 | } 85 | 86 | throw new Exception(MessageConsole::string(sprintf('Path %s not allowed', $path))); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Filesystem/File.php: -------------------------------------------------------------------------------- 1 | load($this->encode($html)); 25 | } 26 | 27 | /** 28 | * @param string $html 29 | * 30 | * @return string 31 | */ 32 | protected function encode(string $html): string 33 | { 34 | $html = htmlentities($html, ENT_COMPAT, 'UTF-8', false); 35 | $html = mb_convert_encoding($html, 'UTF-8', mb_list_encodings()); 36 | $html = htmlspecialchars_decode($html); 37 | 38 | return $html; 39 | } 40 | 41 | /** 42 | * @param string $html 43 | * 44 | * @return self 45 | */ 46 | protected function load(string $html): self 47 | { 48 | libxml_use_internal_errors(true); 49 | 50 | $this->dom = new DOMDocument(); 51 | $this->dom->recover = true; 52 | $this->dom->preserveWhiteSpace = false; 53 | $this->dom->substituteEntities = false; 54 | $this->dom->loadHtml($html, LIBXML_NOBLANKS | LIBXML_ERR_NONE); 55 | $this->dom->encoding = 'utf-8'; 56 | 57 | libxml_use_internal_errors(false); 58 | 59 | return $this; 60 | } 61 | 62 | /** 63 | * @param string $query 64 | * @param \DOMElement $node = null 65 | * 66 | * @return \DOMNodeList 67 | */ 68 | public function query(string $query, DOMElement $node = null): DOMNodeList 69 | { 70 | return (new DOMXpath($this->dom))->query($query, $node); 71 | } 72 | 73 | /** 74 | * @param string $query 75 | * @param \DOMElement $node = null 76 | * @param int $item = 0 77 | * 78 | * @return ?\DOMElement 79 | */ 80 | public function queryItem(string $query, DOMElement $node = null, int $item = 0): ?DOMElement 81 | { 82 | return $this->query($query, $node)->item($item); 83 | } 84 | 85 | /** 86 | * @param \DOMElement $node 87 | * 88 | * @return string 89 | */ 90 | public function toHtml(DOMElement $node): string 91 | { 92 | return $this->dom->saveHTML($node); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/View/Template.php: -------------------------------------------------------------------------------- 1 | 2 |

PHP Changes Cheatsheet

3 | 4 | 5 |
6 | 21 |
-------------------------------------------------------------------------------- /src/views/templates/info-version.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |

PHP

4 |
5 | 6 | 7 |
-------------------------------------------------------------------------------- /src/views/templates/info.php: -------------------------------------------------------------------------------- 1 |
2 | 5 | 6 |
7 | 8 |
9 |
-------------------------------------------------------------------------------- /src/views/templates/layout.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <?= $title; ?> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | --------------------------------------------------------------------------------