3v4l.org

run code in 300+ PHP versions simultaneously
<?php /** * Copyright 2014 Facebook, Inc. * * You are hereby granted a non-exclusive, worldwide, royalty-free license to * use, copy, modify, and distribute this software in source code or binary * form for use in connection with the web services and APIs provided by * Facebook. * * As with any software that integrates with the Facebook platform, your use * of this software is subject to the Facebook Developer Principles and * Policies [http://developers.facebook.com/policy/]. This copyright notice * shall be included in all copies or substantial portions of the software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ namespace Facebook; /** * Class FacebookSession * @package Facebook * @author Fosco Marotto <fjm@fb.com> * @author David Poll <depoll@fb.com> */ class FacebookSession { /** * @var string */ private static $defaultAppId; /** * @var string */ private static $defaultAppSecret; /** * @var string The token string for the session */ private $token; /** * @var array */ private $signedRequestData; /** * When creating a Session from an access_token, use: * var $session = new FacebookSession($accessToken); * This will validate the token and provide a Session object ready for use. * It will throw a SessionException in case of error. * * @param string $accessToken * @param array $parsedSignedRequest The signed request data if available */ public function __construct($accessToken, $parsedSignedRequest = null) { $this->token = $accessToken; $this->signedRequestData = $parsedSignedRequest; } /** * Returns the access token * * @return string */ public function getToken() { return $this->token; } /** * Returns the signed request data from the sessions creation * * @return null|array */ public function getSignedRequestData() { return $this->signedRequestData; } /** * Returns a property from the signed request data if available * * @param string $keyname * * @return null|mixed */ public function getSignedRequestProperty($keyname) { if (isset($this->signedRequestData[$keyname])) { return $this->signedRequestData[$keyname]; } return null; } /** * Returns user_id from signed request data if available * * @return null|string */ public function getUserId() { return $this->getSignedRequestProperty('user_id'); } /** * getSessionInfo - Makes a request to /debug_token with the appropriate * arguments to get debug information about the sessions token. * * @param string|null $appId * @param string|null $appSecret * * @return GraphSessionInfo */ public function getSessionInfo($appId = null, $appSecret = null) { $targetAppId = static::_getTargetAppId($appId); $targetAppSecret = static::_getTargetAppSecret($appSecret); return (new FacebookRequest( static::newAppSession($targetAppId, $targetAppSecret), 'GET', '/debug_token', array( 'input_token' => $this->getToken(), ) ))->execute()->getGraphObject(GraphSessionInfo::className()); } /** * getLongLivedSession - Returns a new Facebook session resulting from * extending a short-lived access token. If this session is not * short-lived, returns $this. * * @param string|null $appId * @param string|null $appSecret * * @return FacebookSession */ public function getLongLivedSession($appId = null, $appSecret = null) { $targetAppId = static::_getTargetAppId($appId); $targetAppSecret = static::_getTargetAppSecret($appSecret); $params = array( 'client_id' => $targetAppId, 'client_secret' => $targetAppSecret, 'grant_type' => 'fb_exchange_token', 'fb_exchange_token' => $this->getToken() ); // The response for this endpoint is not JSON, so it must be handled // differently, not as a GraphObject. $response = (new FacebookRequest( self::newAppSession($targetAppId, $targetAppSecret), 'GET', '/oauth/access_token', $params ))->execute()->getResponse(); if ($response) { return new FacebookSession($response['access_token']); } else { return $this; } } /** * getExchangeToken - Returns an exchange token string which can be sent * back to clients and exchanged for a device-linked access token. * * @param string|null $appId * @param string|null $appSecret * * @return string */ public function getExchangeToken($appId = null, $appSecret = null) { $targetAppId = static::_getTargetAppId($appId); $targetAppSecret = static::_getTargetAppSecret($appSecret); // Redirect URI is being removed as a requirement. Passing an empty string. $params = array( 'client_id' => $targetAppId, 'access_token' => $this->getToken(), 'client_secret' => $targetAppSecret, 'redirect_uri' => '' ); $response = (new FacebookRequest( self::newAppSession($targetAppId, $targetAppSecret), 'GET', '/oauth/client_code', $params ))->execute()->getGraphObject(); return $response->getProperty('code'); } /** * validate - Ensures the current session is valid, throwing an exception if * not. Fetches token info from Facebook. * * @param string|null $appId Application ID to use * @param string|null $appSecret App secret value to use * * @return boolean */ public function validate($appId = null, $appSecret = null) { $targetAppId = static::_getTargetAppId($appId); $targetAppSecret = static::_getTargetAppSecret($appSecret); $info = $this->getSessionInfo($targetAppId, $targetAppSecret); return self::validateSessionInfo($info, $targetAppId); } /** * validateTokenInfo - Ensures the provided GraphSessionInfo object is valid, * throwing an exception if not. Ensures the appId matches, * that the token is valid and has not expired. * * @param GraphSessionInfo $tokenInfo * @param string|null $appId Application ID to use * * @return boolean * * @throws FacebookSDKException */ public static function validateSessionInfo(GraphSessionInfo $tokenInfo, $appId = null) { $targetAppId = static::_getTargetAppId($appId); if ($tokenInfo->getAppId() !== $targetAppId || !$tokenInfo->isValid() || $tokenInfo->getExpiresAt() === null || $tokenInfo->getExpiresAt()->getTimestamp() < time()) { throw new FacebookSDKException( 'Session has expired, or is not valid for this app.', 601 ); } return true; } /** * newSessionFromSignedRequest - Returns a FacebookSession for a * given signed request. * * @param string $signedRequest * @param string $state * * @return FacebookSession */ public static function newSessionFromSignedRequest($signedRequest, $state = null) { $parsedRequest = self::parseSignedRequest($signedRequest, $state); if (isset($parsedRequest['code']) && !isset($parsedRequest['oauth_token'])) { return self::newSessionAfterValidation($parsedRequest); } return new FacebookSession($parsedRequest['oauth_token'], $parsedRequest); } /** * newSessionAfterValidation - Returns a FacebookSession for a * validated & parsed signed request. * * @param array $parsedSignedRequest * * @return FacebookSession * * @throws FacebookRequestException */ private static function newSessionAfterValidation($parsedSignedRequest) { $params = array( 'client_id' => self::$defaultAppId, 'redirect_uri' => '', 'client_secret' => self::$defaultAppSecret, 'code' => $parsedSignedRequest['code'] ); $response = (new FacebookRequest( self::newAppSession( self::$defaultAppId, self::$defaultAppSecret), 'GET', '/oauth/access_token', $params ))->execute()->getResponse(); if (isset($response['access_token'])) { return new FacebookSession( $response['access_token'], $parsedSignedRequest ); } throw FacebookRequestException::create( json_encode($parsedSignedRequest), $parsedSignedRequest, 401 ); } /** * Parses a signed request. * * @param string $signedRequest * @param string $state * * @return array * * @throws FacebookSDKException */ private static function parseSignedRequest($signedRequest, $state) { if (strpos($signedRequest, '.') !== false) { list($encodedSig, $encodedData) = explode('.', $signedRequest, 2); $sig = self::_base64UrlDecode($encodedSig); $data = json_decode(self::_base64UrlDecode($encodedData), true); if (isset($data['algorithm']) && $data['algorithm'] === 'HMAC-SHA256') { $expectedSig = hash_hmac( 'sha256', $encodedData, self::$defaultAppSecret, true ); if (strlen($sig) !== strlen($expectedSig)) { throw new FacebookSDKException( 'Invalid signature on signed request.', 602 ); } $validate = 0; for ($i = 0; $i < strlen($sig); $i++) { $validate |= ord($expectedSig[$i]) ^ ord($sig[$i]); } if ($validate !== 0) { throw new FacebookSDKException( 'Invalid signature on signed request.', 602 ); } if (!isset($data['oauth_token']) && !isset($data['code'])) { throw new FacebookSDKException( 'Invalid signed request, missing OAuth data.', 603 ); } if ($state && (!isset($data['state']) || $data['state'] != $state)) { throw new FacebookSDKException( 'Signed request did not pass CSRF validation.', 604 ); } return $data; } else { throw new FacebookSDKException( 'Invalid signed request, using wrong algorithm.', 605 ); } } else { throw new FacebookSDKException( 'Malformed signed request.', 606 ); } } /** * newAppSession - Returns a FacebookSession configured with a token for the * application which can be used for publishing and requesting app-level * information. * * @param string|null $appId Application ID to use * @param string|null $appSecret App secret value to use * * @return FacebookSession */ public static function newAppSession($appId = null, $appSecret = null) { $targetAppId = static::_getTargetAppId($appId); $targetAppSecret = static::_getTargetAppSecret($appSecret); return new FacebookSession( $targetAppId . '|' . $targetAppSecret ); } /** * setDefaultApplication - Will set the static default appId and appSecret * to be used for API requests. * * @param string $appId Application ID to use by default * @param string $appSecret App secret value to use by default */ public static function setDefaultApplication($appId, $appSecret) { self::$defaultAppId = $appId; self::$defaultAppSecret = $appSecret; } /** * _getTargetAppId - Will return either the provided app Id or the default, * throwing if neither are populated. * * @param string $appId * * @return string * * @throws FacebookSDKException */ public static function _getTargetAppId($appId = null) { $target = ($appId ?: self::$defaultAppId); if (!$target) { throw new FacebookSDKException( 'You must provide or set a default application id.', 700 ); } return $target; } /** * _getTargetAppSecret - Will return either the provided app secret or the * default, throwing if neither are populated. * * @param string $appSecret * * @return string * * @throws FacebookSDKException */ public static function _getTargetAppSecret($appSecret = null) { $target = ($appSecret ?: self::$defaultAppSecret); if (!$target) { throw new FacebookSDKException( 'You must provide or set a default application secret.', 701 ); } return $target; } /** * Base64 decoding which replaces characters: * + instead of - * / instead of _ * @link http://en.wikipedia.org/wiki/Base64#URL_applications * * @param string $input base64 url encoded input * * @return string The decoded string */ public static function _base64UrlDecode($input) { return base64_decode(strtr($input, '-_', '+/')); } }

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.0.110.0040.00416.87
8.0.100.0000.00816.90
8.0.90.0000.00816.98
8.0.80.0030.01716.88
8.0.70.0040.00416.88
8.0.60.0040.00416.82
8.0.50.0080.00016.89
8.0.30.0100.01017.13
8.0.20.0120.00617.40
8.0.10.0000.00716.89
8.0.00.0140.00416.71
7.4.240.0020.00516.55
7.4.230.0040.00416.44
7.4.220.0130.00716.51
7.4.210.0090.00816.61
7.4.200.0040.00416.44
7.4.190.0040.00416.58
7.4.160.0100.00716.28
7.4.150.0160.00317.40
7.4.140.0130.00517.86
7.4.130.0130.00616.50
7.4.120.0100.00916.52
7.4.110.0100.00616.55
7.4.100.0110.00616.49
7.4.90.0060.01216.60
7.4.80.0090.00919.39
7.4.70.0180.00416.51
7.4.60.0120.00616.47
7.4.50.0050.00316.66
7.4.40.0060.01022.77
7.4.30.0060.01316.43
7.4.00.0070.00714.86
7.3.300.0050.00216.35
7.3.290.0030.01216.30
7.3.280.0080.00916.35
7.3.270.0130.00417.40
7.3.260.0100.00716.46
7.3.250.0130.00716.26
7.3.240.0090.00816.52
7.3.230.0120.01116.39
7.3.210.0080.00816.57
7.3.200.0130.01019.39
7.3.190.0040.01516.44
7.3.180.0180.00016.31
7.3.170.0000.01716.34
7.3.160.0060.01416.61
7.3.120.0030.01514.88
7.3.10.0050.00716.69
7.3.00.0040.00916.37
7.2.330.0120.00916.51
7.2.320.0070.01416.33
7.2.310.0060.01116.54
7.2.300.0070.01016.29
7.2.290.0080.00916.46
7.2.130.0070.00716.78
7.2.120.0050.00716.76
7.2.110.0030.01016.53
7.2.100.0010.01016.46
7.2.90.0040.00616.76
7.2.80.0090.00416.64
7.2.70.0060.00816.78
7.2.60.0060.00716.78
7.2.50.0080.00316.83
7.2.40.0050.00716.54
7.2.30.0060.00616.77
7.2.20.0060.00816.54
7.2.10.0070.00516.63
7.2.00.0050.00716.79
7.1.250.0030.00915.65
7.1.200.0080.00315.66
7.1.70.0050.00516.69
7.1.60.0060.00919.32
7.1.50.0100.01016.82
7.1.00.0070.03022.29
7.0.200.0000.00816.26
7.0.140.0070.06321.97
7.0.100.0070.06720.16
7.0.90.0100.07720.00
7.0.80.0100.07020.04
7.0.70.0170.07719.99
7.0.60.0070.05020.20
7.0.50.0130.07320.48
7.0.40.0100.07720.14
7.0.30.0100.08020.16
7.0.20.0000.05720.08
7.0.10.0030.08720.05
7.0.00.0030.06020.18
5.6.280.0070.07021.14
5.6.250.0170.07020.83
5.6.240.0030.08320.69
5.6.230.0130.07720.66
5.6.220.0070.08320.75
5.6.210.0070.08020.55
5.6.200.0230.06321.25
5.6.190.0130.08021.01
5.6.180.0030.08721.24
5.6.170.0070.08321.09
5.6.160.0070.04021.04
5.6.150.0070.04321.18
5.6.140.0000.05321.18
5.6.130.0030.05021.09
5.6.120.0030.04321.08
5.6.110.0070.03321.02
5.6.100.0030.04021.02
5.6.90.0000.04721.15
5.6.80.0030.04320.43
5.6.70.0070.05020.57
5.6.60.0000.04320.46
5.6.50.0030.03720.48
5.6.40.0100.03020.54
5.6.30.0070.04320.39
5.6.20.0030.05020.51
5.6.10.0030.04020.37
5.6.00.0030.03720.59
5.5.380.0130.07320.43
5.5.370.0100.07020.64
5.5.360.0100.05320.48
5.5.350.0030.07720.54
5.5.340.0070.08020.91
5.5.330.0200.09720.83
5.5.320.0070.08720.98
5.5.310.0070.09020.70
5.5.300.0000.04720.95
5.5.290.0030.05320.69
5.5.280.0100.03720.71
5.5.270.0000.04720.82
5.5.260.0030.06320.95
5.5.250.0070.07020.71
5.5.240.0000.04720.24
5.5.230.0070.03720.29
5.5.220.0100.07320.21
5.5.210.0100.05320.28
5.5.200.0070.03720.25
5.5.190.0000.04320.30
5.5.180.0000.04320.05
5.5.160.0000.04720.33
5.5.150.0000.04320.15
5.5.140.0070.03720.20
5.5.130.0030.03720.34
5.5.120.0030.04020.31
5.5.110.0000.05020.31
5.5.100.0100.03720.24
5.5.90.0100.03320.05
5.5.80.0000.04720.20
5.5.70.0030.04020.13
5.5.60.0070.03320.16
5.5.50.0030.04020.22
5.5.40.0000.04320.17
5.5.30.0070.07720.00
5.5.20.0030.08720.16
5.5.10.0100.05020.08
5.5.00.0130.07320.12
5.4.450.0070.04019.39
5.4.440.0070.04319.23
5.4.430.0030.03719.19
5.4.420.0000.04019.35
5.4.410.0130.03019.33
5.4.400.0000.04318.91
5.4.390.0030.04019.14
5.4.380.0000.04319.16
5.4.370.0030.06719.18
5.4.360.0100.04719.16
5.4.350.0070.03318.89
5.4.340.0030.03718.86
5.4.320.0030.06719.03
5.4.310.0070.04719.16
5.4.300.0070.03718.89
5.4.290.0030.03319.21
5.4.280.0030.04019.03
5.4.270.0000.05019.13
5.4.260.0070.03319.19
5.4.250.0030.03318.90
5.4.240.0070.03718.85
5.4.230.0100.03319.13
5.4.220.0070.04019.21
5.4.210.0000.04719.23
5.4.200.0070.03718.89
5.4.190.0130.05718.89
5.4.180.0070.07719.22
5.4.170.0170.07019.04
5.4.160.0130.07319.01
5.4.150.0130.07018.94
5.4.140.0070.07016.41
5.4.130.0030.07316.39
5.4.120.0070.07016.49
5.4.110.0070.04016.39
5.4.100.0070.06316.50
5.4.90.0100.07316.53
5.4.80.0100.06316.44
5.4.70.0070.05716.55
5.4.60.0100.07316.52
5.4.50.0070.07716.46
5.4.40.0030.07316.31
5.4.30.0130.06716.58
5.4.20.0070.05016.52
5.4.10.0130.06716.52
5.4.00.0100.06315.93
5.3.290.0000.04014.61
5.3.280.0070.03314.70
5.3.270.0100.06714.61
5.3.260.0100.07314.54
5.3.250.0070.08014.71
5.3.240.0070.08014.75
5.3.230.0170.06314.64
5.3.220.0070.07714.57
5.3.210.0030.04714.72
5.3.200.0070.07314.54
5.3.190.0030.07014.61
5.3.180.0100.07714.70
5.3.170.0000.07714.51
5.3.160.0070.07314.60
5.3.150.0030.07714.56
5.3.140.0100.04714.51
5.3.130.0100.07014.50
5.3.120.0170.07014.63
5.3.110.0100.07314.66
5.3.100.0030.07714.12
5.3.90.0030.06314.13
5.3.80.0130.06314.16
5.3.70.0070.07313.97
5.3.60.0030.06314.15
5.3.50.0030.06713.98
5.3.40.0100.07313.94
5.3.30.0030.07313.86
5.3.20.0170.03713.77
5.3.10.0070.07313.73
5.3.00.0000.04313.57

preferences:
47.39 ms | 401 KiB | 5 Q