staylor /
WordPress
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * HTTP API: WP_Http_Streams class |
||
| 4 | * |
||
| 5 | * @package WordPress |
||
| 6 | * @subpackage HTTP |
||
| 7 | * @since 4.4.0 |
||
| 8 | */ |
||
| 9 | |||
| 10 | /** |
||
| 11 | * Core class used to integrate PHP Streams as an HTTP transport. |
||
| 12 | * |
||
| 13 | * @since 2.7.0 |
||
| 14 | * @since 3.7.0 Combined with the fsockopen transport and switched to `stream_socket_client()`. |
||
| 15 | */ |
||
| 16 | class WP_Http_Streams { |
||
| 17 | /** |
||
| 18 | * Send a HTTP request to a URI using PHP Streams. |
||
| 19 | * |
||
| 20 | * @see WP_Http::request For default options descriptions. |
||
| 21 | * |
||
| 22 | * @since 2.7.0 |
||
| 23 | * @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client(). |
||
| 24 | * |
||
| 25 | * @access public |
||
| 26 | * @param string $url The request URL. |
||
| 27 | * @param string|array $args Optional. Override the defaults. |
||
| 28 | * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error |
||
| 29 | */ |
||
| 30 | public function request($url, $args = array()) { |
||
| 31 | $defaults = array( |
||
| 32 | 'method' => 'GET', 'timeout' => 5, |
||
| 33 | 'redirection' => 5, 'httpversion' => '1.0', |
||
| 34 | 'blocking' => true, |
||
| 35 | 'headers' => array(), 'body' => null, 'cookies' => array() |
||
| 36 | ); |
||
| 37 | |||
| 38 | $r = wp_parse_args( $args, $defaults ); |
||
| 39 | |||
| 40 | View Code Duplication | if ( isset( $r['headers']['User-Agent'] ) ) { |
|
| 41 | $r['user-agent'] = $r['headers']['User-Agent']; |
||
| 42 | unset( $r['headers']['User-Agent'] ); |
||
| 43 | } elseif ( isset( $r['headers']['user-agent'] ) ) { |
||
| 44 | $r['user-agent'] = $r['headers']['user-agent']; |
||
| 45 | unset( $r['headers']['user-agent'] ); |
||
| 46 | } |
||
| 47 | |||
| 48 | // Construct Cookie: header if any cookies are set. |
||
| 49 | WP_Http::buildCookieHeader( $r ); |
||
| 50 | |||
| 51 | $arrURL = parse_url($url); |
||
| 52 | |||
| 53 | $connect_host = $arrURL['host']; |
||
| 54 | |||
| 55 | $secure_transport = ( $arrURL['scheme'] == 'ssl' || $arrURL['scheme'] == 'https' ); |
||
| 56 | if ( ! isset( $arrURL['port'] ) ) { |
||
| 57 | if ( $arrURL['scheme'] == 'ssl' || $arrURL['scheme'] == 'https' ) { |
||
| 58 | $arrURL['port'] = 443; |
||
| 59 | $secure_transport = true; |
||
| 60 | } else { |
||
| 61 | $arrURL['port'] = 80; |
||
| 62 | } |
||
| 63 | } |
||
| 64 | |||
| 65 | // Always pass a Path, defaulting to the root in cases such as http://example.com |
||
| 66 | if ( ! isset( $arrURL['path'] ) ) { |
||
| 67 | $arrURL['path'] = '/'; |
||
| 68 | } |
||
| 69 | |||
| 70 | if ( isset( $r['headers']['Host'] ) || isset( $r['headers']['host'] ) ) { |
||
| 71 | if ( isset( $r['headers']['Host'] ) ) |
||
| 72 | $arrURL['host'] = $r['headers']['Host']; |
||
| 73 | else |
||
| 74 | $arrURL['host'] = $r['headers']['host']; |
||
| 75 | unset( $r['headers']['Host'], $r['headers']['host'] ); |
||
| 76 | } |
||
| 77 | |||
| 78 | /* |
||
| 79 | * Certain versions of PHP have issues with 'localhost' and IPv6, It attempts to connect |
||
| 80 | * to ::1, which fails when the server is not set up for it. For compatibility, always |
||
| 81 | * connect to the IPv4 address. |
||
| 82 | */ |
||
| 83 | if ( 'localhost' == strtolower( $connect_host ) ) |
||
| 84 | $connect_host = '127.0.0.1'; |
||
| 85 | |||
| 86 | $connect_host = $secure_transport ? 'ssl://' . $connect_host : 'tcp://' . $connect_host; |
||
| 87 | |||
| 88 | $is_local = isset( $r['local'] ) && $r['local']; |
||
| 89 | $ssl_verify = isset( $r['sslverify'] ) && $r['sslverify']; |
||
| 90 | View Code Duplication | if ( $is_local ) { |
|
| 91 | /** |
||
| 92 | * Filters whether SSL should be verified for local requests. |
||
| 93 | * |
||
| 94 | * @since 2.8.0 |
||
| 95 | * |
||
| 96 | * @param bool $ssl_verify Whether to verify the SSL connection. Default true. |
||
| 97 | */ |
||
| 98 | $ssl_verify = apply_filters( 'https_local_ssl_verify', $ssl_verify ); |
||
| 99 | } elseif ( ! $is_local ) { |
||
| 100 | /** |
||
| 101 | * Filters whether SSL should be verified for non-local requests. |
||
| 102 | * |
||
| 103 | * @since 2.8.0 |
||
| 104 | * |
||
| 105 | * @param bool $ssl_verify Whether to verify the SSL connection. Default true. |
||
| 106 | */ |
||
| 107 | $ssl_verify = apply_filters( 'https_ssl_verify', $ssl_verify ); |
||
| 108 | } |
||
| 109 | |||
| 110 | $proxy = new WP_HTTP_Proxy(); |
||
| 111 | |||
| 112 | $context = stream_context_create( array( |
||
| 113 | 'ssl' => array( |
||
| 114 | 'verify_peer' => $ssl_verify, |
||
| 115 | //'CN_match' => $arrURL['host'], // This is handled by self::verify_ssl_certificate() |
||
| 116 | 'capture_peer_cert' => $ssl_verify, |
||
| 117 | 'SNI_enabled' => true, |
||
| 118 | 'cafile' => $r['sslcertificates'], |
||
| 119 | 'allow_self_signed' => ! $ssl_verify, |
||
| 120 | ) |
||
| 121 | ) ); |
||
| 122 | |||
| 123 | $timeout = (int) floor( $r['timeout'] ); |
||
| 124 | $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000; |
||
| 125 | $connect_timeout = max( $timeout, 1 ); |
||
| 126 | |||
| 127 | // Store error number. |
||
| 128 | $connection_error = null; |
||
| 129 | |||
| 130 | // Store error string. |
||
| 131 | $connection_error_str = null; |
||
| 132 | |||
| 133 | if ( !WP_DEBUG ) { |
||
| 134 | // In the event that the SSL connection fails, silence the many PHP Warnings. |
||
| 135 | if ( $secure_transport ) |
||
| 136 | $error_reporting = error_reporting(0); |
||
| 137 | |||
| 138 | View Code Duplication | if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) |
|
| 139 | $handle = @stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); |
||
| 140 | else |
||
| 141 | $handle = @stream_socket_client( $connect_host . ':' . $arrURL['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); |
||
| 142 | |||
| 143 | if ( $secure_transport ) |
||
| 144 | error_reporting( $error_reporting ); |
||
|
0 ignored issues
–
show
|
|||
| 145 | |||
| 146 | View Code Duplication | } else { |
|
| 147 | if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) |
||
| 148 | $handle = stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); |
||
| 149 | else |
||
| 150 | $handle = stream_socket_client( $connect_host . ':' . $arrURL['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); |
||
| 151 | } |
||
| 152 | |||
| 153 | if ( false === $handle ) { |
||
| 154 | // SSL connection failed due to expired/invalid cert, or, OpenSSL configuration is broken. |
||
| 155 | if ( $secure_transport && 0 === $connection_error && '' === $connection_error_str ) |
||
| 156 | return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) ); |
||
| 157 | |||
| 158 | return new WP_Error('http_request_failed', $connection_error . ': ' . $connection_error_str ); |
||
| 159 | } |
||
| 160 | |||
| 161 | // Verify that the SSL certificate is valid for this request. |
||
| 162 | if ( $secure_transport && $ssl_verify && ! $proxy->is_enabled() ) { |
||
| 163 | if ( ! self::verify_ssl_certificate( $handle, $arrURL['host'] ) ) |
||
| 164 | return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) ); |
||
| 165 | } |
||
| 166 | |||
| 167 | stream_set_timeout( $handle, $timeout, $utimeout ); |
||
| 168 | |||
| 169 | if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) //Some proxies require full URL in this field. |
||
| 170 | $requestPath = $url; |
||
| 171 | else |
||
| 172 | $requestPath = $arrURL['path'] . ( isset($arrURL['query']) ? '?' . $arrURL['query'] : '' ); |
||
| 173 | |||
| 174 | $strHeaders = strtoupper($r['method']) . ' ' . $requestPath . ' HTTP/' . $r['httpversion'] . "\r\n"; |
||
| 175 | |||
| 176 | $include_port_in_host_header = ( |
||
| 177 | ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) || |
||
| 178 | ( 'http' == $arrURL['scheme'] && 80 != $arrURL['port'] ) || |
||
| 179 | ( 'https' == $arrURL['scheme'] && 443 != $arrURL['port'] ) |
||
| 180 | ); |
||
| 181 | |||
| 182 | if ( $include_port_in_host_header ) { |
||
| 183 | $strHeaders .= 'Host: ' . $arrURL['host'] . ':' . $arrURL['port'] . "\r\n"; |
||
| 184 | } else { |
||
| 185 | $strHeaders .= 'Host: ' . $arrURL['host'] . "\r\n"; |
||
| 186 | } |
||
| 187 | |||
| 188 | if ( isset($r['user-agent']) ) |
||
| 189 | $strHeaders .= 'User-agent: ' . $r['user-agent'] . "\r\n"; |
||
| 190 | |||
| 191 | if ( is_array($r['headers']) ) { |
||
| 192 | foreach ( (array) $r['headers'] as $header => $headerValue ) |
||
| 193 | $strHeaders .= $header . ': ' . $headerValue . "\r\n"; |
||
| 194 | } else { |
||
| 195 | $strHeaders .= $r['headers']; |
||
| 196 | } |
||
| 197 | |||
| 198 | if ( $proxy->use_authentication() ) |
||
| 199 | $strHeaders .= $proxy->authentication_header() . "\r\n"; |
||
| 200 | |||
| 201 | $strHeaders .= "\r\n"; |
||
| 202 | |||
| 203 | if ( ! is_null($r['body']) ) |
||
| 204 | $strHeaders .= $r['body']; |
||
| 205 | |||
| 206 | fwrite($handle, $strHeaders); |
||
| 207 | |||
| 208 | if ( ! $r['blocking'] ) { |
||
| 209 | stream_set_blocking( $handle, 0 ); |
||
| 210 | fclose( $handle ); |
||
| 211 | return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
||
| 212 | } |
||
| 213 | |||
| 214 | $strResponse = ''; |
||
| 215 | $bodyStarted = false; |
||
| 216 | $keep_reading = true; |
||
| 217 | $block_size = 4096; |
||
| 218 | if ( isset( $r['limit_response_size'] ) ) |
||
| 219 | $block_size = min( $block_size, $r['limit_response_size'] ); |
||
| 220 | |||
| 221 | // If streaming to a file setup the file handle. |
||
| 222 | if ( $r['stream'] ) { |
||
| 223 | if ( ! WP_DEBUG ) |
||
| 224 | $stream_handle = @fopen( $r['filename'], 'w+' ); |
||
| 225 | else |
||
| 226 | $stream_handle = fopen( $r['filename'], 'w+' ); |
||
| 227 | if ( ! $stream_handle ) |
||
| 228 | return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); |
||
| 229 | |||
| 230 | $bytes_written = 0; |
||
| 231 | while ( ! feof($handle) && $keep_reading ) { |
||
| 232 | $block = fread( $handle, $block_size ); |
||
| 233 | if ( ! $bodyStarted ) { |
||
| 234 | $strResponse .= $block; |
||
| 235 | if ( strpos( $strResponse, "\r\n\r\n" ) ) { |
||
| 236 | $process = WP_Http::processResponse( $strResponse ); |
||
| 237 | $bodyStarted = true; |
||
| 238 | $block = $process['body']; |
||
| 239 | unset( $strResponse ); |
||
| 240 | $process['body'] = ''; |
||
| 241 | } |
||
| 242 | } |
||
| 243 | |||
| 244 | $this_block_size = strlen( $block ); |
||
| 245 | |||
| 246 | if ( isset( $r['limit_response_size'] ) && ( $bytes_written + $this_block_size ) > $r['limit_response_size'] ) { |
||
| 247 | $this_block_size = ( $r['limit_response_size'] - $bytes_written ); |
||
| 248 | $block = substr( $block, 0, $this_block_size ); |
||
| 249 | } |
||
| 250 | |||
| 251 | $bytes_written_to_file = fwrite( $stream_handle, $block ); |
||
| 252 | |||
| 253 | if ( $bytes_written_to_file != $this_block_size ) { |
||
| 254 | fclose( $handle ); |
||
| 255 | fclose( $stream_handle ); |
||
| 256 | return new WP_Error( 'http_request_failed', __( 'Failed to write request to temporary file.' ) ); |
||
| 257 | } |
||
| 258 | |||
| 259 | $bytes_written += $bytes_written_to_file; |
||
| 260 | |||
| 261 | $keep_reading = !isset( $r['limit_response_size'] ) || $bytes_written < $r['limit_response_size']; |
||
| 262 | } |
||
| 263 | |||
| 264 | fclose( $stream_handle ); |
||
| 265 | |||
| 266 | } else { |
||
| 267 | $header_length = 0; |
||
| 268 | while ( ! feof( $handle ) && $keep_reading ) { |
||
| 269 | $block = fread( $handle, $block_size ); |
||
| 270 | $strResponse .= $block; |
||
| 271 | if ( ! $bodyStarted && strpos( $strResponse, "\r\n\r\n" ) ) { |
||
| 272 | $header_length = strpos( $strResponse, "\r\n\r\n" ) + 4; |
||
| 273 | $bodyStarted = true; |
||
| 274 | } |
||
| 275 | $keep_reading = ( ! $bodyStarted || !isset( $r['limit_response_size'] ) || strlen( $strResponse ) < ( $header_length + $r['limit_response_size'] ) ); |
||
| 276 | } |
||
| 277 | |||
| 278 | $process = WP_Http::processResponse( $strResponse ); |
||
| 279 | unset( $strResponse ); |
||
| 280 | |||
| 281 | } |
||
| 282 | |||
| 283 | fclose( $handle ); |
||
| 284 | |||
| 285 | $arrHeaders = WP_Http::processHeaders( $process['headers'], $url ); |
||
|
0 ignored issues
–
show
The variable
$process does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
| 286 | |||
| 287 | $response = array( |
||
| 288 | 'headers' => $arrHeaders['headers'], |
||
| 289 | // Not yet processed. |
||
| 290 | 'body' => null, |
||
| 291 | 'response' => $arrHeaders['response'], |
||
| 292 | 'cookies' => $arrHeaders['cookies'], |
||
| 293 | 'filename' => $r['filename'] |
||
| 294 | ); |
||
| 295 | |||
| 296 | // Handle redirects. |
||
| 297 | if ( false !== ( $redirect_response = WP_Http::handle_redirects( $url, $r, $response ) ) ) |
||
| 298 | return $redirect_response; |
||
| 299 | |||
| 300 | // If the body was chunk encoded, then decode it. |
||
| 301 | if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] ) |
||
| 302 | $process['body'] = WP_Http::chunkTransferDecode($process['body']); |
||
| 303 | |||
| 304 | View Code Duplication | if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders['headers']) ) |
|
| 305 | $process['body'] = WP_Http_Encoding::decompress( $process['body'] ); |
||
| 306 | |||
| 307 | if ( isset( $r['limit_response_size'] ) && strlen( $process['body'] ) > $r['limit_response_size'] ) |
||
| 308 | $process['body'] = substr( $process['body'], 0, $r['limit_response_size'] ); |
||
| 309 | |||
| 310 | $response['body'] = $process['body']; |
||
| 311 | |||
| 312 | return $response; |
||
| 313 | } |
||
| 314 | |||
| 315 | /** |
||
| 316 | * Verifies the received SSL certificate against its Common Names and subjectAltName fields. |
||
| 317 | * |
||
| 318 | * PHP's SSL verifications only verify that it's a valid Certificate, it doesn't verify if |
||
| 319 | * the certificate is valid for the hostname which was requested. |
||
| 320 | * This function verifies the requested hostname against certificate's subjectAltName field, |
||
| 321 | * if that is empty, or contains no DNS entries, a fallback to the Common Name field is used. |
||
| 322 | * |
||
| 323 | * IP Address support is included if the request is being made to an IP address. |
||
| 324 | * |
||
| 325 | * @since 3.7.0 |
||
| 326 | * @static |
||
| 327 | * |
||
| 328 | * @param stream $stream The PHP Stream which the SSL request is being made over |
||
| 329 | * @param string $host The hostname being requested |
||
| 330 | * @return bool If the cerficiate presented in $stream is valid for $host |
||
| 331 | */ |
||
| 332 | public static function verify_ssl_certificate( $stream, $host ) { |
||
| 333 | $context_options = stream_context_get_options( $stream ); |
||
| 334 | |||
| 335 | if ( empty( $context_options['ssl']['peer_certificate'] ) ) |
||
| 336 | return false; |
||
| 337 | |||
| 338 | $cert = openssl_x509_parse( $context_options['ssl']['peer_certificate'] ); |
||
| 339 | if ( ! $cert ) |
||
| 340 | return false; |
||
| 341 | |||
| 342 | /* |
||
| 343 | * If the request is being made to an IP address, we'll validate against IP fields |
||
| 344 | * in the cert (if they exist) |
||
| 345 | */ |
||
| 346 | $host_type = ( WP_Http::is_ip_address( $host ) ? 'ip' : 'dns' ); |
||
| 347 | |||
| 348 | $certificate_hostnames = array(); |
||
| 349 | if ( ! empty( $cert['extensions']['subjectAltName'] ) ) { |
||
| 350 | $match_against = preg_split( '/,\s*/', $cert['extensions']['subjectAltName'] ); |
||
| 351 | foreach ( $match_against as $match ) { |
||
| 352 | list( $match_type, $match_host ) = explode( ':', $match ); |
||
| 353 | if ( $host_type == strtolower( trim( $match_type ) ) ) // IP: or DNS: |
||
| 354 | $certificate_hostnames[] = strtolower( trim( $match_host ) ); |
||
| 355 | } |
||
| 356 | } elseif ( !empty( $cert['subject']['CN'] ) ) { |
||
| 357 | // Only use the CN when the certificate includes no subjectAltName extension. |
||
| 358 | $certificate_hostnames[] = strtolower( $cert['subject']['CN'] ); |
||
| 359 | } |
||
| 360 | |||
| 361 | // Exact hostname/IP matches. |
||
| 362 | if ( in_array( strtolower( $host ), $certificate_hostnames ) ) |
||
| 363 | return true; |
||
| 364 | |||
| 365 | // IP's can't be wildcards, Stop processing. |
||
| 366 | if ( 'ip' == $host_type ) |
||
| 367 | return false; |
||
| 368 | |||
| 369 | // Test to see if the domain is at least 2 deep for wildcard support. |
||
| 370 | if ( substr_count( $host, '.' ) < 2 ) |
||
| 371 | return false; |
||
| 372 | |||
| 373 | // Wildcard subdomains certs (*.example.com) are valid for a.example.com but not a.b.example.com. |
||
| 374 | $wildcard_host = preg_replace( '/^[^.]+\./', '*.', $host ); |
||
| 375 | |||
| 376 | return in_array( strtolower( $wildcard_host ), $certificate_hostnames ); |
||
| 377 | } |
||
| 378 | |||
| 379 | /** |
||
| 380 | * Determines whether this class can be used for retrieving a URL. |
||
| 381 | * |
||
| 382 | * @static |
||
| 383 | * @access public |
||
| 384 | * @since 2.7.0 |
||
| 385 | * @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client(). |
||
| 386 | * |
||
| 387 | * @param array $args Optional. Array of request arguments. Default empty array. |
||
| 388 | * @return bool False means this class can not be used, true means it can. |
||
| 389 | */ |
||
| 390 | public static function test( $args = array() ) { |
||
| 391 | if ( ! function_exists( 'stream_socket_client' ) ) |
||
| 392 | return false; |
||
| 393 | |||
| 394 | $is_ssl = isset( $args['ssl'] ) && $args['ssl']; |
||
| 395 | |||
| 396 | if ( $is_ssl ) { |
||
| 397 | if ( ! extension_loaded( 'openssl' ) ) |
||
| 398 | return false; |
||
| 399 | if ( ! function_exists( 'openssl_x509_parse' ) ) |
||
| 400 | return false; |
||
| 401 | } |
||
| 402 | |||
| 403 | /** |
||
| 404 | * Filters whether streams can be used as a transport for retrieving a URL. |
||
| 405 | * |
||
| 406 | * @since 2.7.0 |
||
| 407 | * |
||
| 408 | * @param bool $use_class Whether the class can be used. Default true. |
||
| 409 | * @param array $args Request arguments. |
||
| 410 | */ |
||
| 411 | return apply_filters( 'use_streams_transport', true, $args ); |
||
| 412 | } |
||
| 413 | } |
||
| 414 | |||
| 415 | /** |
||
| 416 | * Deprecated HTTP Transport method which used fsockopen. |
||
| 417 | * |
||
| 418 | * This class is not used, and is included for backward compatibility only. |
||
| 419 | * All code should make use of WP_Http directly through its API. |
||
| 420 | * |
||
| 421 | * @see WP_HTTP::request |
||
| 422 | * |
||
| 423 | * @since 2.7.0 |
||
| 424 | * @deprecated 3.7.0 Please use WP_HTTP::request() directly |
||
| 425 | */ |
||
| 426 | class WP_HTTP_Fsockopen extends WP_HTTP_Streams { |
||
| 427 | // For backward compatibility for users who are using the class directly. |
||
| 428 | } |
||
| 429 |
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: