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

Все сниппеты с тэгом «php»

PHP
PHP: Hypertext Preprocessor — «PHP: препроцессор гипертекста»; первоначально Personal Home Page Tools — «Инструменты для создания персональных веб-страниц»; произносится пи-эйч-пи) — скриптовый язык общего назначения, интенсивно применяемый для разработки веб-приложений.


Kosuha606
  • Репутация: 11
  • Сниппеты: 11
  • Ревизии: 0

Даже в коде Yii2 в yii/db/Query, где обработка indexBy идет индексация перебором rows в цикле, хотя есть способ использовать array_column для индексации массива по ключу. пример:

$users = [
    ['id' => 1, 'name' => 'Bob', 'age' => 30],
    ['id' => 12, 'name' => 'Alice', 'age' => 20],
    ['id' => 34, 'name' => 'Trump', 'age' => 69]
];

$users = array_column($users, null, 'id');
 
// В результате
$users = [
    1 => ['id' => 1, 'name' => 'Bob', 'age' => 30],
    12 => ['id' => 12, 'name' => 'Alice', 'age' => 20],
    34 => ['id' => 34, 'name' => 'Trump', 'age' => 69]
];

Так же точно в качестве аналога ArrayHelper::map из Yii2 можно использовать этот же array_column

$users = [
    ['id' => 1, 'name' => 'Bob', 'age' => 30],
    ['id' => 12, 'name' => 'Alice', 'age' => 20],
    ['id' => 34, 'name' => 'Trump', 'age' => 69]
];

$users = array_column($users, 'id', 'name');
 
// В результате
$users = [
    1 => 'Bob',
    12 => 'Alice',
    34 => 'Trump'
];
Gravatar image
Nepster
  • Репутация: 151
  • Сниппеты: 19
  • Ревизии: 0
$str = '0123456789 abcdKDLAD !@#$%^&*()_+ абвгЖЗИКМ chỉđơngiảnlà 是印刷及排版';
$result = preg_replace('#(*UTF8)[^\pL\pN\s]+#u','', $str);
echo $result; // 0123456789 abcdKDLAD  абвгЖЗИКМ chỉđơngiảnlà 是印刷及排版

Так-же можно удалять и пробелы убрав метасимвол \s.

Roman Zhuravlev
  • Репутация: 6
  • Сниппеты: 3
  • Ревизии: 0

Пусковой скрипт для запуска cron-команд в docker-контенере. Проверяет cron-выражение и запускает команду. Умеет выход по сигналам SIGTERM и SIGINT. В отличии от стандартного cron-демона следующую команду не запустит пока не выполнит предыдущую. Удобно использовать при разработке c docker-compose. В логах докера показывает что запускалось, когда, и с каким результатом.

#!/usr/bin/env php
<?php
/**
 * Скрипт для запуска команды по расписанию, для замены cron-а в сети из docker-контейнеров.
 *
 * Пример команды, которая будет запускаться каждую минуту:
 * docker/php/cron.php "* * * * *" php yii rate/update
 *
 * Зависимости:
 * "mtdowling/cron-expression": "~1.2.0"
 *
 * @author Roman Zhuravlev <zhuravljov@gmail.com>
 */

require(__DIR__ . '/../../vendor/autoload.php');

// Params
$params = $_SERVER['argv'];
array_shift($params);
$expression = array_shift($params);
$command = implode(' ', $params);
$schedule = \Cron\CronExpression::factory($expression);

// Signal handler
$signal = 0;
$signalHandler = function ($sigNum) use (&$signal) {
    $signal = $sigNum;
};
pcntl_signal(SIGTERM, $signalHandler);
pcntl_signal(SIGINT, $signalHandler);

// Loop
printLog('Cron started');
while (true) {
    sleep(60 - time() % 60);
    pcntl_signal_dispatch();
    if ($signal) {
        printLog("Cron stopped by signal $signal");
        exit(0);
    }
    if (!$schedule->isDue()) {
        continue;
    }
    $startedAt = microtime(true);
    printLog("[started] command: $command", $startedAt);
    passthru($command, $exitCode);
    $finishedAt = microtime(true);
    $totalTime = sprintf('%01.3f', $finishedAt - $startedAt);
    printLog("[finished] duration $totalTime s, exit code $exitCode");
    if ($exitCode) {
        exit($exitCode);
    }
}

function printLog($message, $time = null)
{
    echo date('Y-m-d H:i:s', $time ?? time()), ' ' , $message, PHP_EOL;
}
Kosuha606
  • Репутация: 11
  • Сниппеты: 11
  • Ревизии: 0

Функция, позволяющая перевести PhpOffice Spreadsheet в таблицу PhpWord Table, Чтобы напечатать таблицу в .doc файле. Пришлось сделать эту функцию, потому что перевод XLS->HTML и HTML->DOC работает плохо для таблиц.

Из недочетов метода:

  1. addCell - использует константую ширину ячейки, это можно доработать
  2. Объединение ячеек учитывается только по ширине, не по высоте.

Делал этот метод для того, чтобы основная логика генерации таблиц была в XLS и чтобы генерация DOC использовала эту таблицу уже готовую и вставляла таблицу в заготовленный шаблон DOC.

private function convertXlsToDocTable(Worksheet $sheet, Table $table)
{
    foreach ($sheet->getRowIterator() as $rowIndex => $row) {
        $table->addRow();
        $prevMergeRange = null;
        $cellIterator = $row->getCellIterator();
        $cellIterator->setIterateOnlyExistingCells(false);
        foreach ($cellIterator as $cellIndex => $cell) {
            $value = $cell->getValue();
            $mergeRange = $cell->getMergeRange();
            if ($mergeRange && $prevMergeRange == $mergeRange) {
                continue;
            }
            if ($mergeRange) {
                $mergeCount = 0;
                foreach ($row as $mergeCell) {
                    if ($mergeRange == $mergeCell['mergeRange']) {
                        $mergeCount++;
                    }
                }
                $table->addCell(2000, ['gridSpan' => $mergeCount])->addText($value);
                $prevMergeRange = $mergeRange;
            } else {
                $table->addCell(2000, [])->addText($value);
            }
        }
    }

    return $table;
}
Gravatar image
ivaaaan
  • Репутация: 3
  • Сниппеты: 1
  • Ревизии: 0
function urange($start, $end, $step)
{
    if (!is_callable($step)) {
        return range($start, $end, $step);
    }

    $helper = function ($current, $start) use ($end, $step, &$helper) {
        if ($start > $end) {
            return $current;
        }
        $current[] = $start;
        return $helper($current, $step($start));
    };
    
    return $helper([], $start);
}

print_r(urange(20, 39, function ($n) {
    $next = ($n / 10) % 10;
    return $n + ($next >= 1 ? $next : 1);
}));

print_r(urange(1, 40, function ($n) {
	return $n+1;
}));

print_r(urange(1, 40, function ($n) {
    return $n+$n;
}));
Gravatar image
Insolita
  • Репутация: 7
  • Сниппеты: 3
  • Ревизии: 1

При сохранении груповых данных, зачастую требуется сопоставить, то-что у нас уже хранится в БД и то-что пришло с формы, для этого приходится сверять элименты по уникальному полю, данный снипет, из одной незамысловатой строки, вернет массив с уникальными ключами. Затем можно уже проверять на isset($models_by_id[$id]) или array_diff_key, ну и т.д.

$models_by_id=Model::find()->indexBy('id')->all(); //yii 2 path @mista twista

$models=Model::model()->findAll(); //yii 1
$models_by_id=array_combine(array_keys(CHtml::listData($models, 'id', 'id')),$models);
$models_by_id=array_combine(array_column($model,'id'),$model); //since php5.5

Gravatar image
Insolita
  • Репутация: 7
  • Сниппеты: 3
  • Ревизии: 1
<?php
namespace common\tests;

use Codeception\Util\Debug;
use yii\console\Application;
use yii\db\ActiveQuery;
use yii\db\Connection;
use yii\helpers\ArrayHelper;
use yii\helpers\Console;
use yii\helpers\VarDumper;

/**
 * Useful set for performance optimization in console scripts, and test researches
 *
 * Trait ProfilingInspectorTrait
 *
 * @package common\tests
 */
trait ProfilingInspectorTrait
{
    
    /**
     * @param \yii\db\Query|ActiveQuery $query
     * @param \yii\db\Connection        $db
     */
    protected function showQuery(\yii\db\Query $query, Connection $db)
    {
        $sql = $query->prepare($db->queryBuilder)->createCommand($db)->rawSql;
        $this->resolvedOutput($sql, __FUNCTION__);
    }
    
    /**
     * @param \yii\db\Query|ActiveQuery $query
     * @param \yii\db\Connection        $db
     */
    protected function explainQuery(\yii\db\Query $query, Connection $db)
    {
        $sql = $query->prepare($db->queryBuilder)->createCommand($db)->rawSql;
        $sql = 'EXPLAIN: ' . implode(PHP_EOL, $db->createCommand('EXPLAIN ' . $sql)->queryColumn('QUERY PLAN'));
        $this->resolvedOutput($sql, __FUNCTION__);
    }
    
    /**
     * @param \yii\db\Query|ActiveQuery $query
     * @param \yii\db\Connection        $db
     */
    protected function analyzeQuery(\yii\db\Query $query, Connection $db)
    {
        $sql = $query->prepare($db->queryBuilder)->createCommand($db)->rawSql;
        $sql = 'ANALYZE: ' . implode(PHP_EOL, $db->createCommand('EXPLAIN ANALYZE ' . $sql)->queryColumn('QUERY PLAN'));
        $this->resolvedOutput($sql, __FUNCTION__);
    }
    
    /**
     * Show execution time for specified callback and time elapsed from app start
     * Return real function result
     *
     * @example
     *         $result=$this->timeIt(function(){
     *         $data = User::find()->where(['<','id', 100])->all();
     *         return ArrayHelper::map($data,'id','name');
     *         });
     *
     * @param \Closure $function
     * @param string   $comment Additional log comment
     *
     * @return mixed
     */
    protected function timeIt(\Closure $function, string $comment = '')
    {
        $mStart = microtime(true);
        $result = $function();
        $mEnd = microtime(true);
        $this->resolvedOutput(
            [
                'timeDelta' => ($mEnd - $mStart),
                'elapsedTime'=>\Yii::getLogger()->elapsedTime
            ],
            __FUNCTION__ . ':' . $comment
        );
        return $result;
    }
    
    /**
     * Show execution time, memory usage, and peek memory check for specified callback
     * Return real function result
     *
     * @example
     *           $result1=$this->inspectIt(function(){
     *           $data = User::find()->where(['<','id', 100])->all();
     *           return ArrayHelper::map($data,'id','name');
     *           },'Object result');
     *           $result2 = $this->inspectIt(function(){
     *           $data = User::find()->where(['<','id', 100])->asArray()->all();
     *           $result = ArrayHelper::map($data,'id','name');
     *           unset($data);
     *           return $result;
     *           },'As Array result');
     *
     * @param \Closure $function
     * @param string   $comment Additional log comment
     *
     * @return mixed
     */
    protected function inspectIt(\Closure $function, string $comment = '')
    {
        $start = \Yii::getLogger()->elapsedTime;
        $start_memory = memory_get_usage();
        $start_peek = memory_get_peak_usage();
        $result = $function();
        $end_memory = memory_get_usage();
        $end_peek = memory_get_peak_usage();
        $end = \Yii::getLogger()->elapsedTime;
        $this->resolvedOutput(
            [
                'timeDelta' => ($end - $start),
                'memory'    => [
                    'from'                => \Yii::$app->formatter->asSize($start_memory),
                    'to'                  => \Yii::$app->formatter->asSize($end_memory),
                    'delta'               => \Yii::$app->formatter->asSize(($end_memory - $start_memory)),
                    'peekMemoryIncreased' => ($end_peek > $start_peek) ? \Yii::$app->formatter->asSize($start_peek)
                        . ' +' . \Yii::$app->formatter->asSize($end_peek - $start_peek) : 'no',
                ],
            ],
            __FUNCTION__ . ':' . $comment
        );
        return $result;
    }
    
    /**
     * Show profile log for specified callback
     * Return real function result
     *
     * @example
     *         $result=$this->profileIt(function(){
     *         $data = User::find()->where(['<','id', 100])->all();
     *         return ArrayHelper::map($data,'id','name');
     *         });
     *
     * @param \Closure $function
     * @param string   $comment Additional log comment
     *
     * @return mixed
     */
    protected function profileIt(\Closure $function, string $comment = '')
    {
        $id = uniqid('profile_');
        \Yii::beginProfile($id, __FUNCTION__ . ':' . $id);
        $result = $function();
        \Yii::endProfile($id, __FUNCTION__ . ':' . $id);
        $profile = \Yii::getLogger()->getProfiling([]);
        $map = ArrayHelper::getColumn($profile, 'info');
        $profile = array_slice($profile, array_search($id, $map));
        unset($map);
        $this->resolvedOutput($profile, __FUNCTION__ . ':' . $id . ':' . $comment);
        return $result;
    }
    
    /**
     * @param $message
     */
    protected function resolvedOutput($message, $subj = ''): void
    {
        $divider = '============= ' . $subj . ' ===============';
        if (YII_ENV_TEST === true) {
            Debug::debug($divider);
            Debug::debug($message);
        } elseif (\Yii::$app instanceof Application) {
            Console::output(Console::ansiFormat($divider . PHP_EOL, [Console::FG_BLUE]));
            Console::output(Console::ansiFormat(VarDumper::export($message) . PHP_EOL, [Console::FG_GREEN]));
        } else {
            \Yii::trace($message, get_called_class().':'.$subj);
        }
    }
   
}
Valentin Sayik
  • Репутация: 37
  • Сниппеты: 5
  • Ревизии: 0

API которое описанное в этом сниппете будет следовать следующим правилам:

  • Возвращает только JSON
  • Для любого запроса клиент должен пройти аутентификацию
  • Аутентификация производится через OAuth2, Grant Type = password.
  • Разные версии API будут храниться на поддоменах (например v1.api.example.com)

Для написания API было использовано php + Symfony 3 + следующие бандлы:

Продолжение »

Gravatar image
jumper423
  • Репутация: 58
  • Сниппеты: 9
  • Ревизии: 2

GitHub

Описание

Пакет создан для стандартизации всех сервисов по разгадыванию капч. У каждого сервиса есть свои особенности и теперь Вам надо будет всего лишь взглянуть на документацию конкретного сервиса чтобы правильно всё сделать. Так же пакет покрывает всю функциональсть сервисов. Если же Вам будет чего-то нехватать или будут предложения, я буду только рад их услышать.

Особенности

  • Подходит для всех сервисов по распознаванию капч
  • Можно легко добавить новый сервис, используя уже готовый движок
  • Быстрая и интуительно понятная настройка
  • Распознавание как по пути до файла, так и по ссылки
  • ReCaptcha v2 без браузера
  • Полная документация
  • Покрыт тестами

Продолжение »

OKyJIucT
  • Репутация: 15
  • Сниппеты: 8
  • Ревизии: 0
<?php
function rgb2hex($rgb)
{
    $hex = "#";
    foreach ($rgb as $color) {
    	$hex .= str_pad(dechex($color), 2, "0", STR_PAD_LEFT);
    }
    return $hex;
}

$rgb = [175, 175, 175];
$hex = rgb2hex($rgb); // #afafaf