Для получения полного доступа
зарегистрируйтесь.

Section:
Sub-section::
Languages:


Gravatar image
tetraset
  • Reputation: 6
  • Snippets: 3
  • Revisions: 0
function chunkedCopy($from, $to) {
    # 1 meg at a time, you can adjust this.
    $buffer_size = 1048576;
    $ret = 0;
    $fin = fopen($from, "rb");
    $fout = fopen($to, "w");
    while(!feof($fin)) {
    	$ret += fwrite($fout, fread($fin, $buffer_size));
    }
    fclose($fin);
    fclose($fout);
    return $ret;
}
SilverFire
  • Reputation: 3
  • Snippets: 1
  • Revisions: 0

The function above checks, whether the current controller's action is the same as defined in the defaultRoute property of application.

function isHomePage() {
  $actualRoute = Yii::$app->controller->getRoute();

  list($controller, $actionId) = Yii::$app->createController('');
  $actionId = !empty($actionId) ? $actionId : $controller->defaultAction;
  $defaultRoute = $controller->getUniqueId() . '/' . $actionId;

  return $actualRoute === $defaultRoute;
}
Gravatar image
blacksmoke26
  • Reputation: 13
  • Snippets: 11
  • Revisions: 0
/**
 * Split the SQL dump code and return as queries array.
 * @param string $raw SQL code to parse
 * @return array List of queries
 */
function splitSqlText ( $raw ) {
	// the regex needs a trailing semicolon
	$raw = trim ( (string) $raw );

	if ( substr ( $raw, -1 ) !== ";") {
		$raw .= ";";
	}

	// i spent 3 days figuring out this line
	preg_match_all( "/(?>[^;']|(''|(?>'([^']|\\')*[^\\\]')".
		"))+;/ixU", $raw, $matches, PREG_SET_ORDER );

	$querySplit = [];

	foreach ( $matches as $match ) {
		// get rid of the trailing semicolon
		$querySplit[] = substr( $match[0], 0, -1 );
	}

	return $querySplit;
}
Gravatar image
blacksmoke26
  • Reputation: 13
  • Snippets: 11
  • Revisions: 0
/**
 * Validate MySQL Timestamp
 * @param string $value Value to check (Y-m-d h:i:s)
 * @return bool TRUE on valid | FALSE anyway
 */
function isTimestampValid ( $value ) {
	$date = array();
	if ( !preg_match ('/^(?<y>19\d\d|20\d\d)\-(?<m>0[1-9]|1[0-2])\-' .
		'(?<d>0\d|[1-2]\d|3[0-1]) (?<h>0\d|1\d|2[0-3]' .
		')\:(?<i>[0-5][0-9])\:(?<s>[0-5][0-9])$/', $value, $date) ) {
		return false;
	}

	return checkdate ( $date['m'], $date['d'], $date['y'] );
}

/************
 * EXAMPLE
 ***********/
var_dump ( isTimestampValid ('2016-09-10 23:21:09') );

/***********
 * OUTPUT
 **********/
# (bool) true
Gravatar image
blacksmoke26
  • Reputation: 13
  • Snippets: 11
  • Revisions: 0
/**
 * Generate mime types list using apache svn defination
 * @link http://php.net/manual/en/function.mime-content-type.php#107798
 * @return array [key=>value] pairs of mime types (extension=>mime_type)
 */
function generateMimeTypes () {
	$list = [];
	$url = 'http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types';
    
	foreach ( @explode ( "\n", @file_get_contents ($url) ) as $x ) {
		if ( isset( $x[0] )
			&& $x[0] !== '#'
			&& preg_match_all ( '#([^\s]+)#', $x, $out )
			&& isset( $out[1] )
			&& ( $c = count ( $out[1] ) ) > 1 ) {
			for ( $i = 1; $i < $c; $i++ ) {
				$key = (string) $out[1][$i];
				$list[$key] = $out[1][0];
			}
		}
	}

	return @ksort($list, \SORT_STRING )
		? $list
		: [];
}

/************
 * EXAMPLE
 ***********/
print_r ( generateMimeTypes () );

/***********
 * OUTPUT
 **********/
 [
    '3dml' => 'text/vnd.in3d.3dml'
    '3ds' => 'image/x-3ds'
    '3g2' => 'video/3gpp2'
    '3gp' => 'video/3gpp'
    '7z' => 'application/x-7z-compressed'
    'aab' => 'application/x-authorware-bin'
    'aac' => 'audio/x-aac'
    'aam' => 'application/x-authorware-map'
    'aas' => 'application/x-authorware-seg'
    'abw' => 'application/x-abiword'
    'ac' => 'application/pkix-attr-cert'
    'acc' => 'application/vnd.americandynamics.acc'
    'ace' => 'application/x-ace-compressed'
    'acu' => 'application/vnd.acucobol'
    'acutc' => 'application/vnd.acucorp'
    'adp' => 'audio/adpcm'
    'aep' => 'application/vnd.audiograph'
    'afm' => 'application/x-font-type1'
    'afp' => 'application/vnd.ibm.modcap'
    'ahead' => 'application/vnd.ahead.space'
    'ai' => 'application/postscript'
    'aif' => 'audio/x-aiff',
    ...
]
Gravatar image
blacksmoke26
  • Reputation: 13
  • Snippets: 11
  • Revisions: 0
/**
 * Divide an array into a desired number of split lists
 * @link http://www.php.net/manual/en/function.array-chunk.php#75022
 * @param array $list The Array
 * @param int $size Partition Size
 * @return array The partitioned array
 */
function columnsPartition ( array $list, $size ) {
	$listLen = count ( $list );

	if ( !$listLen || $size < 1 ) {
		return [];
	}

	$partLen = floor ( $listLen / $size );
	$partRem = $listLen % $size;
	$partition = [];
	$mark = 0;

	for ( $px = 0; $px < $size; $px++ ) {
		$increment = ( $px < $partRem ) ? $partLen + 1 : $partLen;

		$partition[ $px ] = array_slice ( $list, $mark, $increment );
		$mark += $increment;
	}

	return $partition;
}

/************
 * EXAMPLE
 ***********/
var_dump ( columnsPartition(range('A','I'), 3) );

/***********
 * OUTPUT
 **********/
array (size=3)
  0 => 
    array (size=3)
      0 => string 'A' (length=1)
      1 => string 'B' (length=1)
      2 => string 'C' (length=1)
  1 => 
    array (size=3)
      0 => string 'D' (length=1)
      1 => string 'E' (length=1)
      2 => string 'F' (length=1)
  2 => 
    array (size=3)
      0 => string 'G' (length=1)
      1 => string 'H' (length=1)
      2 => string 'I' (length=1)
Gravatar image
blacksmoke26
  • Reputation: 13
  • Snippets: 11
  • Revisions: 0
/**
 * Strip text longer then given length
 * @param string $text Text to be stripped
 * @param int $length Length of chars to keep
 * @param string $glueChar (optional) Show when length exceeded
 * @return string|null Stripped text | Text was empty
 */
function getCharsByLength ( $text, $length, $glueChar = '...' ) {
	if ( !trim ($text ) ) {
		return null;
	}

	/** @var int $actualLength */
	$actualLength = function_exists('mb_strlen')
		? mb_strlen($text)
		: strlen($text);

	// desired length is same or less, return as it is
	if ( $actualLength <= $length ) {
		return $text;
	}

	return function_exists ( 'mb_substr' )
		? mb_substr ($text, 0, $length, 'utf8' ) . $glueChar
		: substr ($text, 0, $length ) . $glueChar;
}

/************
 * EXAMPLE
 ***********/
getCharsByLength ('Νο εαμ σθμμο vολθτπατ. Εα εστ ομνεσ ιμπερδιετ εφφιcιαντθρ', 10);

/***********
 * OUTPUT
 **********/
# Νο εαμ σθμ...
IStranger
  • Reputation: 17
  • Snippets: 8
  • Revisions: 0

High-performance function checks whether specified array contains only integer values (or integer-numeric strings):


/**
 * Checks whether all elements of an array are integers (integer value or string with integer value).
 * Note: this is very efficient method can be used for array with 10000+ items.
 *
 * @param int[]|string[] $array One dimensional array to check
 *
 * @return bool
 */ 
function hasOnlyIntEntries(array $array)
{
    return ctype_digit(join('', $array));
}
IStranger
  • Reputation: 17
  • Snippets: 8
  • Revisions: 0

When we work with some API interface, it often have Rate-Limit, usually certain number of http-requests per unit of time (see for example Twitter API Rate Limit).

This helper can help you efficiently handle these restrictions.

Helper code:


/**
 * Helper for work with some API.
 */
class ApiHelper
{

    /**
     * Wraps specified callback function and retries of execution in the case when callback throws specified exception.
     * Used Exponential BackOff algorithm for evaluating of timeouts between retries of callback execution.
     *
     * Example:
     * <code>
     *  $sendHttpRequest = function ($pageNum) use ($httpClient){
     *      $httpClient->sendGet('http://example.com?pageNum=' . $pageNum);
     *  };
     *
     *  $wrappedFn = ApiHelper::wrapUsingExponentialBackOff($sendHttpRequest, 5000, '\TooManyRequestsHttpException');
     *
     *  // We perform 100 requests. But remote server has RateLimit.
     *  for ($i = 1; $i <= 100; $i++) {
     *      // $sendHttpRequest($i);     // request without wrapper
     *      $wrappedFn($i);              // request with wrapper
     *      // this wrapper retry callback execution in the case of \TooManyRequestsHttpException exception.
     *  }
     * </code>
     *
     * @param \Closure $callbackFn                  Callback function.
     * @param int      $maxSleepMs                  Max value of timeout between callback execution.
     * @param string   $rateLimitExceptionClassName Exception that should throw callback on rate limit.
     * @param int      $maxRetries                  Max number of retries.
     * @param \Closure $onTooManyRequest            Callback function that performed on each RateLimit exception.
     *
     * @return \Closure
     */
    public static function wrapUsingExponentialBackOff(\Closure $callbackFn, $maxSleepMs, $rateLimitExceptionClassName, $maxRetries = 10, \Closure $onTooManyRequest = null)
    {
        $wrapFn = function () use ($callbackFn, $maxSleepMs, $rateLimitExceptionClassName, $maxRetries, $onTooManyRequest) {

            $currentTry    = 0;
            $retriesRemain = $maxRetries;

            while ($retriesRemain-- > 0) {

                try {
                    $currentTry++;
                    return call_user_func_array($callbackFn, func_get_args());

                } catch (\Exception $exception) {

                    // retries only throttling errors
                    if ($exception instanceof $rateLimitExceptionClassName) {
                        $backOffDuration = static::_getSleepDuration($currentTry, 10, $maxSleepMs);

                        if ($onTooManyRequest) {
                            $onTooManyRequest($exception, $backOffDuration, $retriesRemain, $currentTry);
                        }

                        usleep($backOffDuration * 1000);
                    } else {
                        throw $exception;
                    }

                }

            }

            throw new \Exception('ExponentialBackOff: Too many retries of function call [maxRetries=' . $maxRetries . ']');
        };

        return $wrapFn;
    }

    protected static function _getSleepDuration($currentTry, $minSleepMs, $maxSleepMs)
    {
        $currentSleepMs = (int)($minSleepMs * pow(2, $currentTry));

        return min($currentSleepMs, $maxSleepMs);
    }
}

How it use

  1. Prepare your callback function that performs some API method. This callback function should throw certain exception when API not allows perform method (restricts by Rate-Limit).
  2. Wrap your callback function using ApiHelper::wrapUsingExponentialBackOff() method
  3. Execute wrapped callback function (instead original function).
$sendHttpRequest = function ($pageNum) use ($httpClient) {
    $httpClient->sendGet('http://example.com?pageNum=' . $pageNum);
};

$wrappedFn = ApiHelper::wrapUsingExponentialBackOff($sendHttpRequest, 5000, '\TooManyRequestsHttpException');

// We perform 100 requests. But remote server has RateLimit.
for ($i = 1; $i <= 100; $i++) {
    // $sendHttpRequest($i);     // request without wrapper
    $wrappedFn($i);              // request with wrapper
    // this wrapper retry callback execution in the case of \TooManyRequestsHttpException exception.
}

How it works

This helper uses "Exponential backoff" algorithm. The main idea of this algorithm is to reduce the rate at which you are executing an operation by introducing delays. Therefore when you are "backing off" you are waiting for a period of time before attempting to execute the operation again. Wrapped callback function $wrappedFn will retry to execute specified original callback function $sendHttpRequest if it throws exception.

Snippet,  PHP

mb_ucfirst

samdark
  • Reputation: 349
  • Snippets: 57
  • Revisions: 5

Mulibyte versions of ucfirst() which works well with unicode.

function mb_ucfirst($string, $encoding = 'UTF-8') {
  $firstChar = mb_strtoupper(mb_substr($string, 0, 1, $encoding), $encoding);
  return $firstChar . mb_substr($string, 1, mb_strlen($string, $encoding), $encoding);
}