how to win?
PHP 7.2.0, the create_function() is deprecated.
Thanks for your help,
or wait for developers?
Edited and cleared Code
return create_function( '', "
global $chery_core_version;
$path = trailingslashit( dirname( __FILE__ ) ) . 'cherry-core.php';
$data = get_file_data( $path, array(
'version' => 'Version'
) );
if ( isset( $data['version'] ) ) {
$version = $data['version'];
}
$old_versions = null;
if ( null !== $chery_core_version ) {
$old_versions = array_keys( $chery_core_version );
}
if ( is_array( $old_versions ) && isset( $old_versions[0] ) ) {
$compare = version_compare( $old_versions[0], $version, '<' );
if ( $compare ) {
$chery_core_version = array();
$chery_core_version[ $version ] = $path;
}
} else {
$chery_core_version = array();
$chery_core_version[ $version ] = $path;
}
" );
Use anonymous functions instead:
return function () {
global $chery_core_version;
$path = trailingslashit(__DIR__) . 'cherry-core.php';
$data = get_file_data( $path, [
'version' => 'Version'
] );
if ( isset( $data['version'] ) ) {
$version = $data['version'];
}
$old_versions = null;
if ( null !== $chery_core_version ) {
$old_versions = array_keys( $chery_core_version );
}
if ( is_array( $old_versions ) && isset( $old_versions[0] ) ) {
$compare = version_compare( $old_versions[0], $version, '<' );
if ( $compare ) {
$chery_core_version = [];
$chery_core_version[ $version ] = $path;
}
} else {
$chery_core_version = [];
$chery_core_version[ $version ] = $path;
}
};
Thanks for clicking on the question. I am trying to find and replace text within a string that contains serialize arrays. For example :
'fgm2wc_options', 'a:19:{s:15:"automatic_empty";N;s:3:"url";s:25:"http://example.com/store/";s:8:"hostname";s:9:"localhost";s:4:"port";s:4:"3306";s:8:"database";s:22:"apgadmin_store_magento";s:8:"username" ... }
I want to change http://example.com/ to smth else I can do it with str_replace but it will not change the string length indicator ( e.g s:25 ).
This is a function i am using:
function recursive_unserialize_replace( $old_url = '', $new_url = '', $data = '', $serialised = false ) {
$new_url = rtrim( $new_url, '/' );
$data = explode( ', ', $data );
try {
if ( is_string( $data ) && ( $unserialized = #unserialize( $data ) ) !== false ) {
$data = recursive_unserialize_replace( $old_url, $new_url, $unserialized, true );
} elseif ( is_array( $data ) ) {
$_tmp = array( );
foreach ( $data as $key => $value ) {
$_tmp[ $key ] = recursive_unserialize_replace( $old_url, $new_url, $value );
}
$data = $_tmp;
unset( $_tmp );
} else {
if ( is_string( $data ) ) {
$data = str_replace( $old_url, $new_url, $data );
}
}
if ( $serialised ) {
return serialize( $data );
}
} catch( Exception $error ) {
}
return $data;
}
Any ideas ?
For anyone interested this is the solution i came up with:
function unserialize_replace( $old_url = '', $new_url = '', $database_string = '' ) {
if ( substr( $old_url, -1 ) !== '/' ) {
$new_url = rtrim( $new_url, '/' );
}
$serialized_arrays = preg_match_all( "/a:\d+:.*\;\}+/", $database_string, $matches );
if( !empty( $serialized_arrays ) && is_array( $matches ) ) {
foreach ( $matches[ 0 ] as $match ) {
$unserialized = #unserialize( $match );
if ( $unserialized ) {
$buffer = str_replace( $old_url, $new_url, $unserialized );
$buffer = serialize( $buffer );
$database_string = str_replace( $match, $buffer, $database_string );
}
}
}
if ( is_string( $database_string ) ) {
$database_string = str_replace( $old_url, $new_url, $database_string );
}
return $database_string;
}
Thanks for the suggestions. Please let me know if you see anything wrong and anything i can improve
I have this error in my WordPress regarding this plugin, any ideas on how to fix it?
Thank you very much! ;D
<?php
class MinecraftQueryException extends Exception
{
// Exception thrown by MinecraftQuery class
}
class MinecraftQuery
{
/*
* Class written by xPaw
*
* Website: http://xpaw.me
* GitHub: https://github.com/xPaw/PHP-Minecraft-Query
*/
const STATISTIC = 0x00;
const HANDSHAKE = 0x09;
private $Socket;
private $Players;
private $Info;
public function Connect( $Ip, $Port = 25565, $Timeout = 3 )
{
if( !is_int( $Timeout ) || $Timeout < 0 )
{
throw new InvalidArgumentException( 'Timeout must be an integer.' );
}
$this->Socket = #FSockOpen( 'udp://' . $Ip, (int)$Port, $ErrNo, $ErrStr, $Timeout );
if( $ErrNo || $this->Socket === false )
{
throw new MinecraftQueryException( 'Could not create socket: ' . $ErrStr );
}
Stream_Set_Timeout( $this->Socket, $Timeout );
Stream_Set_Blocking( $this->Socket, true );
try
{
$Challenge = $this->GetChallenge( );
$this->GetStatus( $Challenge );
}
// We catch this because we want to close the socket, not very elegant
catch( MinecraftQueryException $e )
{
FClose( $this->Socket );
throw new MinecraftQueryException( $e->getMessage( ) );
}
FClose( $this->Socket );
}
public function GetInfo( )
{
return isset( $this->Info ) ? $this->Info : false;
}
public function GetPlayers( )
{
return isset( $this->Players ) ? $this->Players : false;
}
private function GetChallenge( )
{
$Data = $this->WriteData( self :: HANDSHAKE );
if( $Data === false )
{
throw new MinecraftQueryException( 'Failed to receive challenge.' );
}
return Pack( 'N', $Data );
}
private function GetStatus( $Challenge )
{
$Data = $this->WriteData( self :: STATISTIC, $Challenge . Pack( 'c*', 0x00, 0x00, 0x00, 0x00 ) );
if( !$Data )
{
throw new MinecraftQueryException( 'Failed to receive status.' );
}
$Last = '';
$Info = Array( );
$Data = SubStr( $Data, 11 ); // splitnum + 2 int
$Data = Explode( "\x00\x00\x01player_\x00\x00", $Data );
if( Count( $Data ) !== 2 )
{
throw new MinecraftQueryException( 'Failed to parse server\'s response.' );
}
$Players = SubStr( $Data[ 1 ], 0, -2 );
$Data = Explode( "\x00", $Data[ 0 ] );
// Array with known keys in order to validate the result
// It can happen that server sends custom strings containing bad things (who can know!)
$Keys = Array(
'hostname' => 'HostName',
'gametype' => 'GameType',
'version' => 'Version',
'plugins' => 'Plugins',
'map' => 'Map',
'numplayers' => 'Players',
'maxplayers' => 'MaxPlayers',
'hostport' => 'HostPort',
'hostip' => 'HostIp',
'game_id' => 'GameName'
);
foreach( $Data as $Key => $Value )
{
if( ~$Key & 1 )
{
if( !Array_Key_Exists( $Value, $Keys ) )
{
$Last = false;
continue;
}
$Last = $Keys[ $Value ];
$Info[ $Last ] = '';
}
else if( $Last != false )
{
$Info[ $Last ] = $Value;
}
}
// Ints
$Info[ 'Players' ] = IntVal( $Info[ 'Players' ] );
$Info[ 'MaxPlayers' ] = IntVal( $Info[ 'MaxPlayers' ] );
$Info[ 'HostPort' ] = IntVal( $Info[ 'HostPort' ] );
// Parse "plugins", if any
if( $Info[ 'Plugins' ] )
{
$Data = Explode( ": ", $Info[ 'Plugins' ], 2 );
$Info[ 'RawPlugins' ] = $Info[ 'Plugins' ];
$Info[ 'Software' ] = $Data[ 0 ];
if( Count( $Data ) == 2 )
{
$Info[ 'Plugins' ] = Explode( "; ", $Data[ 1 ] );
}
}
else
{
$Info[ 'Software' ] = 'Vanilla';
}
$this->Info = $Info;
if( $Players )
{
$this->Players = Explode( "\x00", $Players );
}
}
private function WriteData( $Command, $Append = "" )
{
$Command = Pack( 'c*', 0xFE, 0xFD, $Command, 0x01, 0x02, 0x03, 0x04 ) . $Append;
$Length = StrLen( $Command );
if( $Length !== FWrite( $this->Socket, $Command, $Length ) )
{
throw new MinecraftQueryException( "Failed to write on socket." );
}
$Data = FRead( $this->Socket, 4096 );
if( $Data === false )
{
throw new MinecraftQueryException( "Failed to read from socket." );
}
if( StrLen( $Data ) < 5 || $Data[ 0 ] != $Command[ 2 ] )
{
return false;
}
return SubStr( $Data, 5 );
}
}
The error message is this:
Cannot redeclare class MinecraftQueryException
plugins/server-status-for-minecraft-pc-pe/libs/MinecraftQuery.php on
line 5
Is there an implementation of OpenID that is under 5K or at least under 10K?
Please format the code with http://beta.phpformatter.com/ with the following settings to get the true size:
Indentation:
Indentation style: {K&R (One true brace style)}
Indent with: {Tabs}
Starting indentation: [1]
Indentation: [1]
Common:
[x] Remove all comments
[x] Remove empty lines
[x] Align assignments statements nicely
[ ] Put a comment with the condition after if, while, for, foreach, declare and catch statements
Improvement:
[x] Remove lines with just a semicolon (;)
[x] Make normal comments (//) from perl comments (#)
[x] Make long opening tag (
Brackets:
[x] Space inside brackets- ( )
[x] Space inside empty brackets- ( )
[x] Space inside block brackets- [ ]
[x] Space inside empty block brackets- [ ]
Edit:
Alix Axel's answer seems great, not perfect but is getting there. BTW: this is 6.4K So it is no longer the smallest, but i'm going through it to clean it up lots more.
<?php
class openID {
function __construct( $url = null, $realm = null, $return = null, $redirect = true, $verify = false ) {
$data = array( );
if ( ( $verify !== true ) && ( self::Value( $_REQUEST, 'openid_mode' ) !== false ) ) {
if ( strcmp( 'id_res', self::Value( $_REQUEST, 'openid_mode' ) ) === 0 ) {
$data[ 'openid.sig' ] = $_REQUEST[ 'openid_sig' ];
$data[ 'openid.mode' ] = 'check_authentication';
$data[ 'openid.signed' ] = $_REQUEST[ 'openid_signed' ];
$data[ 'openid.assoc_handle' ] = $_REQUEST[ 'openid_assoc_handle' ];
if ( array_key_exists( 'openid_op_endpoint', $_REQUEST ) === true ) {
$data[ 'openid.ns' ] = 'http://specs.openid.net/auth/2.0';
}
foreach ( explode( ',', self::Value( $_REQUEST, 'openid_signed' ) ) as $value ) {
$data[ 'openid.' . $value ] = $_REQUEST[ 'openid_' . str_replace( '.', '_', $value ) ];
}
if ( preg_match( '~is_valid\s*:\s*true~i', self::CURL( self::__construct( $_REQUEST[ 'openid_identity' ], false, false, false, true ), $data, 'POST' ) ) > 0 ) {
return self::Value( $_REQUEST, 'openid_claimed_id', self::Value( $_REQUEST, 'openid_identity' ) );
}
}
} else if ( ( $result = self::CURL( $url ) ) !== false ) {
$xml = self::XML( $result );
$server = strval( self::XML( $xml, '//xrd/service/uri', 0 ) );
if ( empty( $server ) === true ) {
$server = strval( self::XML( $xml, '//head/link[#rel="openid.server" or #rel="openid2.provider"]/#href', 0 ) );
}
if ( self::URL( $server ) === true ) {
if ( $redirect === true ) {
$realm = ( isset( $realm ) === true ) ? $realm : sprintf( '%s://%s/', $_SERVER[ "HTTPS" ] ? "https" : "http", $_SERVER[ 'HTTP_HOST' ] );
$return = ( isset( $return ) === true ) ? $return : sprintf( '%s://%s', $_SERVER[ "HTTPS" ] ? "https" : "http", $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ] );
$delegate = ( preg_match( '~http://specs[.]openid[.]net/auth/2[.]0/server~', $result ) > 0 ) ? 'http://specs.openid.net/auth/2.0/identifier_select' : $url;
if ( preg_match( '~rel="openid[.]delegate"|<[^>]*Delegate[^>]*>~i', $result ) > 0 ) {
$delegate = parent::Value( ph()->Text->Regex( $result, '<([^>]*)Delegate[^>]*>([^>]+)</\1Delegate>', 1 ), 0 );
if ( empty( $delegate ) === true ) {
$delegate = strval( self::XML( $xml, '//head/link[#rel="openid.delegate"]/#href', 0, $delegate ) );
}
}
if ( preg_match( '~rel="openid2[.]provider"|http://specs[.]openid[.]net/auth/2[.]0~i', $result ) > 0 ) {
$data[ 'openid.ns' ] = 'http://specs.openid.net/auth/2.0';
if ( preg_match( '~rel="openid2[.]local_id"|<(Local|Canonical)ID[^>]*>~i', $result ) > 0 ) {
$delegate = self::Value( self::Regex( $result, '<(Local|Canonical)ID[^>]*>([^>]+)</\1ID>', 1 ), 0 );
if ( empty( $delegate ) === true ) {
$delegate = strval( self::XML( $xml, '//head/link[#rel="openid2.local_id"]/#href', 0, $delegate ) );
}
}
}
$data[ 'openid.mode' ] = 'checkid_setup';
$data[ 'openid.return_to' ] = $return;
$data[ 'openid.claimed_id' ] = $data[ 'openid.identity' ] = $delegate;
$data[ 'openid.' . ( ( array_key_exists( 'openid.ns', $data ) === true ) ? 'realm' : 'trust_root' ) ] = $realm;
self::Redirect( sprintf( '%s%s%s', $server, ( strpos( $server, '?' ) !== false ) ? '&' : '?', http_build_query( $data, '', '&' ) ) );
}
return $server;
}
}
return false;
}
function CURL( $url, $data = null, $method = "GET", $options = array( ) ) {
$result = false;
if ( ( extension_loaded( "curl" ) === true ) && ( $this->URL( $url ) === true ) ) {
$curl = curl_init( $url );
if ( is_resource( $curl ) === true ) {
curl_setopt( $curl, CURLOPT_FAILONERROR, true );
curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false );
if ( preg_match( "~^GET$~i", $method ) > 0 ) {
curl_setopt( $curl, CURLOPT_HTTPGET, true );
} else if ( preg_match( "~^POST$~i", $method ) > 0 ) {
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $data );
}
$result = curl_exec( $curl );
if ( $result !== false ) {
curl_close( $curl );
}
}
}
return $result;
}
function Redirect( $url, $permanent = false ) {
if ( headers_sent() !== true ) {
header( "Location: " . $url, true, ( $permanent === true ) ? 301 : 302 );
}
exit( );
}
function Regex( $string, $pattern, $key = null, $modifiers = null, $flag = PREG_PATTERN_ORDER, $default = false ) {
$matches = array( );
if ( preg_match_all( "~" . $pattern . "~" . $modifiers, $string, $matches, $flag ) > 0 ) {
if ( isset( $key ) === true ) {
return ( $key === true ) ? $matches : Value( $matches, $key, $default );
}
return true;
}
return $default;
}
function URL( $value ) {
return (bool) filter_var( $value, FILTER_VALIDATE_URL );
}
function Value( $data, $key = null, $default = false ) {
if ( isset( $key ) === true ) {
foreach ( (array) $key as $value ) {
if ( is_object( $data ) === true ) {
$data = get_object_vars( $data );
}
if ( array_key_exists( $value, (array) $data ) !== true ) {
return $default;
}
$data = $data[ $value ];
}
}
return $data;
}
function XML( $xml, $xpath = null, $key = null, $default = false ) {
if ( extension_loaded( "SimpleXML" ) === true ) {
libxml_use_internal_errors( true );
if ( ( is_string( $xml ) === true ) && ( class_exists( "DOMDocument" ) === true ) ) {
$dom = new DOMDocument();
if ( $dom->loadHTML( $xml ) === true ) {
return $this->XML( simplexml_import_dom( $dom ), $xpath, $key, $default );
}
} else if ( is_object( $xml ) === true ) {
if ( isset( $xpath ) === true ) {
$xml = $xml->xpath( $xpath );
if ( isset( $key ) === true ) {
$xml = $this->Value( $xml, $key, $default );
}
}
return $xml;
}
}
return false;
}
}
new openID( "https://www.google.com/accounts/o8/id" );
?>
Slim down Lightopenid
First of I really don't get your filesize limitation. I find it kind of b*llshit if you ask me....
You could make a call graph(use some sort of dead code detector) of lightopenid to see which functions(only a few are used) you are using. A lot of these big functions aren't used standard for example I believe you can remove the big function protected function request_streams($url, $method='GET', $params=array()) on line 198. I also removed some other functions which aren't used when using it with example-google.php example. My final lightopenid class looks like this(I bet you can even eliminate more code when using call graph/dead code detector).
But now I got the filesize down to 9.8KB. If you compress it you can get it down even more. I got it down to your desired 10K mark, but now the code can not be read by humans anymore.
Code searches:
You could also have a look at these resources/searches to see if any are lighter(I highly doubt that):
https://github.com/search?langOverride=&language=php&q=openid&repo=&start_value=1&type=Repositories&x=17&y=33
http://code.google.com/hosting/search?q=openid+label:php&btn=Search+projects
Inspired by lightopenid and part of phunction (depends on 5 other methods):
public static function OpenID($id, $realm = null, $return = null, $verify = true)
{
$data = array();
if (($verify === true) && (array_key_exists('openid_mode', $_REQUEST) === true))
{
$result = parent::Value($_REQUEST, 'openid_claimed_id', parent::Value($_REQUEST, 'openid_identity'));
if (strcmp('id_res', parent::Value($_REQUEST, 'openid_mode')) === 0)
{
$data['openid.mode'] = 'check_authentication';
foreach (array('ns', 'sig', 'signed', 'assoc_handle') as $key)
{
$data['openid.' . $key] = parent::Value($_REQUEST, 'openid_' . $key);
if (strcmp($key, 'signed') === 0)
{
foreach (explode(',', parent::Value($_REQUEST, 'openid_signed')) as $value)
{
$data['openid.' . $value] = parent::Value($_REQUEST, 'openid_' . str_replace('.', '_', $value));
}
}
}
return (preg_match('~is_valid\s*:\s*true~', self::CURL(self::OpenID($result, false, false, false), array_filter($data, 'is_string'), 'POST')) > 0) ? $result : false;
}
}
else if (($result = self::XML(self::CURL($id))) !== false)
{
$server = null;
$protocol = array
(
array('specs.openid.net/auth/2.0/server', 'specs.openid.net/auth/2.0/signon', array('openid2.provider', 'openid2.local_id')),
array('openid.net/signon/1.1', 'openid.net/signon/1.0', array('openid.server', 'openid.delegate')),
);
foreach ($protocol as $key => $value)
{
while ($namespace = array_shift($value))
{
if (is_array($namespace) === true)
{
$server = strval(self::XML($result, sprintf('//head/link[contains(#rel, "%s")]/#href', $namespace[0]), 0));
$delegate = strval(self::XML($result, sprintf('//head/link[contains(#rel, "%s")]/#href', $namespace[1]), 0, $id));
}
else if (is_object($xml = self::XML($result, sprintf('//xrd/service[contains(type, "http://%s")]', $namespace), 0)) === true)
{
$server = parent::Value($xml, 'uri');
if ($key === 0)
{
$delegate = 'http://specs.openid.net/auth/2.0/identifier_select';
if (strcmp($namespace, 'specs.openid.net/auth/2.0/server') !== 0)
{
$delegate = parent::Value($xml, 'localid', parent::Value($xml, 'canonicalid', $id));
}
}
else if ($key === 1)
{
$delegate = parent::Value($xml, 'delegate', $id);
}
}
if (ph()->Is->URL($server) === true)
{
if (($realm !== false) && ($return !== false))
{
$data['openid.mode'] = 'checkid_setup';
$data['openid.identity'] = $delegate;
$data['openid.return_to'] = parent::URL($return, null, null);
if ($key === 0)
{
$data['openid.ns'] = 'http://specs.openid.net/auth/2.0';
$data['openid.realm'] = parent::URL($realm, false, false);
$data['openid.claimed_id'] = $delegate;
}
else if ($key === 1)
{
$data['openid.trust_root'] = parent::URL($realm, false, false);
}
parent::Redirect(parent::URL($server, null, $data));
}
return $server;
}
}
}
}
return false;
}
Usage:
OpenID('https://www.google.com/accounts/o8/id');
PS: I've updated the code I had previously posted because it was sub-optimal and prone to some bugs.
The slimmest openid implementation I know is LightOpenId
It has got 30kb with comments, so if you run it through that formatter it gets much smaller
EDIT: I found a smaller one here (just 6.6 kb after reformatting)