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

Section:
Sub-section::
Languages:


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

In order to delete item from fragment cache in Yii 2.0 you need to form a key in a special way.

function deleteFragmentCacheByKey($key)
{
    return Yii::$app->cache->delete(['yii\widgets\FragmentCache', $key]);
}
samdark
  • Reputation: 349
  • Snippets: 57
  • Revisions: 5

A short and reliable way to detect if the script is run in Windows environment.

if (DIRECTORY_SEPARATOR === '\\') {
    // ...
}
samdark
  • Reputation: 349
  • Snippets: 57
  • Revisions: 5

There are cases when you need to make sure keys specified are in the beginning of an array in the exact order they are specified.

$data = [
    'orange' => 'orange',
    'apple' => 'tasty',
    'carpet' => 'old',
    'car' => 'fast',
];

$result = orderByKeys($data, ['car', 'carpet']);

Would result in:

$data = [
    'car' => 'fast',
    'carpet' => 'old',
    'orange' => 'orange',
    'apple' => 'tasty',    
];
function orderByKeys(array $array, array $keys)
{
    foreach ($keys as $k => $v) {
        if (!array_key_exists($v, $array)) {
            unset($keys[$k]);
        }
    }

   return array_replace(array_flip($keys), $array);
}

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

PHP has excellenet intl extension which is based on ICU library for algorithms and CLDR data for locale data. The code shows how to get currency symbol by currency code using intl.

Example usage:

echo getCurrencySymbol('EUR');
echo getCurrencySymbol('GBP');

would output and £.

By specifying locale code as a second argument you can get currency representation that is common for that locale:

echo getCurrencySymbol('RUR', 'ru_RU');

would output р..

function getCurrencySymbol($currencyCode, $locale = 'en_US')
{
    $formatter = new \NumberFormatter($locale . '@currency=' . $currencyCode, \NumberFormatter::CURRENCY);
    return $formatter->getSymbol(\NumberFormatter::CURRENCY_SYMBOL);
}

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

While it's kinda pointless, it's possible to use callbacks as URL handlers totally avoiding MVC in the same style as many micro-frameworks do.

require 'vendor/autoload.php';
require 'vendor/yiisoft/yii2/Yii.php';


$app = new CallbackWebApplication([
    'id' => 'MyApplication',
    'basePath' => __DIR__,
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
        ],
    ],
]);

$app->onGet('hello/<name>', function($name) {
    return 'Hello, ' . $name . '!';
});
$app->run();
<?php
class CallbackWebApplication extends \yii\web\Application
{
    private $callbacks = [];

    /**
     * @inheritdoc
     */
    public function handleRequest($request)
    {
        list ($route, $params) = $request->resolve();
        if (preg_match('~callbacks/(\d+)~', $route, $matches) && isset($this->callbacks[$matches[1]])) {
            $result = call_user_func_array($this->callbacks[$matches[1]], $params);
        } else {
            throw new \yii\web\NotFoundHttpException();
        }

        $response = $this->getResponse();
        $response->data = $result;
        return $response;
    }

    public function onGet($pattern, callable $callback)
    {
        // it's possible to implement our own UrlRule class to handle it
        // but I was too lazy
        $callbackIndex = count($this->callbacks);
        $this->callbacks[$callbackIndex] = $callback;
        Yii::$app->getUrlManager()->addRules([
            $pattern => 'callbacks/' . $callbackIndex
        ]);
    }
}
samdark
  • Reputation: 349
  • Snippets: 57
  • Revisions: 5

The approach demonstrated is used in my Sitemap package to allow generating huge sitemaps consisting of hundreds thousangs of locations.

// we'll buffer data in memory in order not to write too often
$bufferSize = 1000;

$filePath = 'test.xml';

$writer = new XMLWriter();
// using memory for buffering
$writer->openMemory();


$writer->startDocument('1.0', 'UTF-8');
$writer->setIndent(true);
$writer->startElement('test');

while ($i < 10000) {                  
	if ($i % $bufferSize) {
		// if buffer is full, flush its contents into the file
		file_put_contents($filePath, $writer->flush(true), FILE_APPEND);
	}
	$writer->writeElement('item', $i);
}

$this->writer->endElement();

$this->writer->endDocument();

// write the rest of the buffer
file_put_contents($filePath, $writer->flush(true), FILE_APPEND);
Snippet,  PHP

Types and in_array

samdark
  • Reputation: 349
  • Snippets: 57
  • Revisions: 5
$array = array('one', 'two');
var_dump(in_array(0, $array)); // true
var_dump(in_array(0, $array, $strict = true)); // false
samdark
  • Reputation: 349
  • Snippets: 57
  • Revisions: 5

Named scopes are quite useful and are familiar to developers who work with Yii. The code shows how to get these in CodeIgniter.

class Post extends Model
{
    function __construct() {
        parent::__construct();
        $this->db->from('post')->order_by("created_at", "desc");
    }
 
    function limit($number) {
        $this->db->limit($number);
        return $this;
    }
 
    function all() {
        return $this->db->get()->result();        
    }
}

$posts = $this->post->limit(10)->find();
foreach($posts as $post) {
	// ..
Snippet,  PHP

PHP4 constructor

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

Legacy PHP4 behavior is still there in current PHP versions. Could lead to debug nightmare.

class Test
{
	public function test()
	{
		echo 'Hello!';
		// it could be less innocent i.e. format disk ;)
	}
}

$test = new Test();

// runs Test::test()
Snippet,  PHP

Factorial

samdark
  • Reputation: 349
  • Snippets: 57
  • Revisions: 5
$fact = function($n) use (&$fact) {
	if ($n === 1) {
        return 1;
    }
 
    return $fact($n - 1) * $n;
};
echo $fact(5); // =120