Форум программистов, компьютерный форум, киберфорум
and_y87
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Yii2 мой flow на старте разработки.

Запись от and_y87 размещена 03.07.2023 в 20:42
Показов 1916 Комментарии 0
Метки yii2

Мне памятка, для себя, что бы не забыть, что за чем делаю)

получается классная структура проекта в итоге

database
Заранее создать 2 базы данных:
  • local_ ...
  • test_ ...

install
Перехожу в репу https://github.com/andy87/yii2-bat-installer
Забираю "yii2-installer.bat", копирую контент в NotePad
меняю кодировку на UTF-8 (Кодировка > Преобразовать в UTF-8)
в корневую папку проекта сохраняю файл под именем `yii2_installer.bat` в расширении `bat`

запускаю исполнение `bat` файла, дожидаюсь завершения установки, далее ... удаляю `yii2_installer.bat`


dirictory
переименовываю директорию `yii` в `app`
  • добавляю в корень проекта директорию `uploads`
  • добавляю в корень проекта директорию `static`

из директории `app` удаляю:
  • (file) Vagrantfile
  • (dir) vagrant

из директории `app` в корень проекта:
  • переношу все файлы ( кроме `.gitignore`)
  • переношу папку `vendor`


В корень проекта добавляю файлы:
.env.example

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# === DATABASE ===
 
DB_DRIVER="mysql"
 
DB_HOST="localhost"
DB_NAME="local_database_name"
DB_USER=""
DB_PASS=""
 
DB_DSN_LOCAL=${DB_DRIVER}:host=${DB_HOST};dbname=${DB_NAME}
 
# // TEST
 
DB_HOST_TEST=${DB_HOST}
DB_NAME_TEST="tests_database_name"
 
DB_DSN_TESTS=${DB_DRIVER}:host=${DB_HOST_TEST};dbname=${DB_NAME_TEST}
 
# === MAILER ===
 
MAILER_FAKE="true"
MAILER_HOST=""
MAILER_USERNAME=""
MAILER_PASSWORD=""
MAILER_PORT="465"
MAILER_DSN="native://default"

.env
Контент аналогичный .enx.example

.gitignore

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# phpstorm project files
.idea
 
# composer vendor dir
/vendor
 
composer.phar
 
# ENV file
.env
 
# yii console commands
/yii_test
/yii_test.bat
 
# netbeans project files
nbproject
 
# zend studio for eclipse project files
.buildpath
.project
.settings
 
# windows thumbnail cache
Thumbs.db
 
# Mac DS_Store Files
.DS_Store
 
# phpunit itself is not needed
phpunit.phar
# local phpunit config
/phpunit.xml
 
# vagrant runtime
/.vagrant
 
# ignore generated files
/app/frontend/web/index.php
/app/frontend/web/index-test.php
/app/frontend/web/robots.txt
/app/backend/web/index.php
/app/backend/web/index-test.php
/app/backend/web/robots.txt



config
Редактирование файлов конфига


/app/common/config/main.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
 
use yii\caching\FileCache;
 
$root = dirname(__DIR__,3);
 
return [
    'aliases' => [
        '@app'   => "$root/app",
        '@upload' => "$root/upload",
        '@static' => "$root/static",
        '@npm'   => '@vendor/npm-asset',
        '@bower' => '@vendor/bower-asset',
    ],
    'vendorPath' =>  "$root/vendor",
    'components' => [
        'cache' => [
            'class' => FileCache::class,
        ],
    ],
];

/app/common/tests/_bootstrap.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
 
use Dotenv\Dotenv;
 
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
defined('YII_APP_BASE_PATH') or define('YII_APP_BASE_PATH', __DIR__.'/../../');
 
require_once YII_APP_BASE_PATH .  '../vendor/autoload.php';
require_once YII_APP_BASE_PATH .  '../vendor/yiisoft/yii2/Yii.php';
require __DIR__ . '/../config/bootstrap.php';
 
Dotenv::createImmutable(YII_APP_BASE_PATH  .  '/../','.env')->load();
 
// Запуск тестов в окружении `common`
// php vendor/bin/codecept run -- -c common
// php vendor/bin/codecept run unit -- -c common \common\tests\unit\{FilePath}}Test.php

/app/console/config/main.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
 
$params = array_merge(
    require __DIR__ . '/../../common/config/params.php',
    require __DIR__ . '/../../common/config/params-local.php',
    require __DIR__ . '/params.php',
    require __DIR__ . '/params-local.php'
);
 
return [
    'id' => 'app-console',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'controllerNamespace' => 'app\console\controllers',
    'aliases' => [
        '@bower' => '@vendor/bower-asset',
        '@npm'   => '@vendor/npm-asset',
    ],
    'controllerMap' => [
        'fixture' => [
            'class' => 'yii\console\controllers\FixtureController',
            'namespace' => 'app\common\fixtures',
        ],
        'migrate' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationPath' => '@app/console/migrations',
        ],
    ],
    'components' => [
        'log' => [
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
    ],
    'params' => $params,
];

/app/frontend/config/main.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
return [
    // ...
    'components' => [
        'request' => [
            'csrfParam' => '...',
            'baseUrl' => ''
        ],
        // ...
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '<_c>/<_a>' => '<_c>/<_a>'
            ],
        ]
    ]
];

/app/frontend/tests/_bootstrap.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
 
use Dotenv\Dotenv;
 
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
defined('YII_APP_BASE_PATH') or define('YII_APP_BASE_PATH', __DIR__ . '/../../');
 
require_once YII_APP_BASE_PATH . '../vendor/autoload.php';
require_once YII_APP_BASE_PATH . '../vendor/yiisoft/yii2/Yii.php';
require_once YII_APP_BASE_PATH . 'common/config/bootstrap.php';
require_once __DIR__ . '/../config/bootstrap.php';
 
Dotenv::createImmutable(YII_APP_BASE_PATH  .  '/../','.env')->load();
 
// Запуск тестов в окружении `frontend`
// php vendor/bin/codecept run -- -c frontend
// php vendor/bin/codecept run unit -- -c frontend \common\tests\unit\{FilePath}}Test.php


/app/backend/config/main.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
return [
    // ...
    'components' => [
        'request' => [
            'csrfParam' => '...',
            'baseUrl' => '/admin'
        ],
        // ...
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '<_c>/<_a>' => '<_c>/<_a>'
            ],
        ]
    ]
];

/app/backend/tests/_bootstrap.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
 
use Dotenv\Dotenv;
 
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
defined('YII_APP_BASE_PATH') or define('YII_APP_BASE_PATH', __DIR__ . '/../../');
 
require_once YII_APP_BASE_PATH . '../vendor/autoload.php';
require_once YII_APP_BASE_PATH . '../vendor/yiisoft/yii2/Yii.php';
require_once YII_APP_BASE_PATH . 'common/config/bootstrap.php';
require_once __DIR__ . '/../config/bootstrap.php';
 
Dotenv::createImmutable(YII_APP_BASE_PATH  .  '/../','.env')->load();
 
// Запуск тестов в окружении `backend`
// php vendor/bin/codecept run -- -c backend
// php vendor/bin/codecept run unit -- -c backend \backend\tests\unit\{FilePath}}Test.php






Создание эндпоинтов
Создание эндпоинтов в директории `app`

В директории `app` создаю файлы:
/app/endpoint.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
use Dotenv\Dotenv;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\web\Application;
 
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
 
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
require __DIR__ . '/common/config/bootstrap.php';
require __DIR__ . '/'.YII_CONTEXT.'/config/bootstrap.php';
 
Dotenv::createImmutable(__DIR__  .  '/../','.env')->load();
 
$config = ArrayHelper::merge(
    require __DIR__ . '/common/config/main.php',
    require __DIR__ . '/common/config/main-local.php',
    require __DIR__ . '/'.YII_CONTEXT.'/config/main.php',
    require __DIR__ . '/'.YII_CONTEXT.'/config/main-local.php'
);
 
try {
 
    $app = new Application($config);
    
} catch (InvalidConfigException $e) {
 
    exit('Fatality exception : ' . $e->getMessage());
}
 
$app->run();

/app/endpoint-test.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
/**
 * @warning: Убедитесь, что этот файл недоступен при развертывании в рабочей среде
 */
 
use Dotenv\Dotenv;
use yii\base\InvalidConfigException;
use yii\web\Application;
 
if (!in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) die('Вам не разрешен доступ к этому файлу.');
 
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
 
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
require __DIR__ . '/common/config/bootstrap.php';
require __DIR__ . '/'.YII_CONTEXT.'/config/bootstrap.php';
 
Dotenv::createImmutable(__DIR__  .  '/../','.env')->load();
 
$config = yii\helpers\ArrayHelper::merge(
    require __DIR__ . '/common/config/main.php',
    require __DIR__ . '/common/config/main-local.php',
    require __DIR__ . '/common/config/test.php',
    require __DIR__ . '/common/config/test-local.php',
    require __DIR__ . '/'.YII_CONTEXT.'/config/main.php',
    require __DIR__ . '/'.YII_CONTEXT.'/config/main-local.php',
    require __DIR__ . '/'.YII_CONTEXT.'/config/test.php',
    require __DIR__ . '/'.YII_CONTEXT.'/config/test-local.php'
);
 
try {
 
    $app = new Application($config);
    
} catch (InvalidConfigException $e) {
 
    exit('Fatality exception : ' . $e->getMessage());
}
 
$app->run();






update файлы проекта:
  • composer.json
    Code
    1
    2
    3
    4
    5
    
    {
      "require": {
        "php": ">=8.0.0"
      }
    }

environments
Настройка окружений
/app/environments/dev

/app/environments/dev/yii.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/env php
<?php
/**
 * Yii console bootstrap file.
 */
 
use Dotenv\Dotenv;
use yii\base\InvalidConfigException;
use yii\console\Application;
 
try
{
    defined('YII_DEBUG') or define('YII_DEBUG', true);
    defined('YII_ENV') or define('YII_ENV', 'dev');
    defined('PATH_APP') or define('PATH_APP', __DIR__ . '/app/');
 
    require __DIR__ . '/vendor/autoload.php';
    require __DIR__ . '/vendor/yiisoft/yii2/Yii.php';
    require PATH_APP. 'common/config/bootstrap.php';
    require PATH_APP. 'console/config/bootstrap.php';
 
    Dotenv::createImmutable(__DIR__,'.env')->load();
 
    $config = yii\helpers\ArrayHelper::merge(
        require PATH_APP. 'common/config/main.php',
        require PATH_APP. 'common/config/main-local.php',
        require PATH_APP. 'console/config/main.php',
        require PATH_APP. 'console/config/main-local.php'
    );
 
    $application = new Application($config);
 
    $exitCode = $application->run();
 
    exit($exitCode);
 
} catch (InvalidConfigException $e) {
 
    exit('Fatality:' . $e->getMessage());
}

/app/environments/dev/yii_test.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/env php
<?php
/**
 * Yii console bootstrap file.
 */
 
use Dotenv\Dotenv;
use yii\console\Application;
use yii\helpers\ArrayHelper;
use yii\base\InvalidConfigException;
 
try
{
    defined('YII_DEBUG') or define('YII_DEBUG', true);
    defined('YII_ENV') or define('YII_ENV', 'test');
    defined('PATH_APP') or define('PATH_APP', __DIR__ . '/app/');
 
    require __DIR__.'/vendor/autoload.php';
    require __DIR__.'/vendor/yiisoft/yii2/Yii.php';
    require PATH_APP.'common/config/bootstrap.php';
    require PATH_APP.'console/config/bootstrap.php';
 
    Dotenv::createImmutable(__DIR__, '.env')->load();
 
    $config = ArrayHelper::merge(
        require PATH_APP.'common/config/main.php',
        require PATH_APP. 'common/config/main-local.php',
        require PATH_APP. 'common/config/test.php',
        require PATH_APP. 'common/config/test-local.php',
        require PATH_APP. 'console/config/main.php',
        require PATH_APP. 'console/config/main-local.php',
        require PATH_APP . 'console/config/test.php',
        require PATH_APP. 'console/config/test-local.php'
    );
 
    $application = new Application($config);
 
    $exitCode = $application->run();
 
    exit($exitCode);
 
} catch (InvalidConfigException $e) {
 
    exit('Fatality:' . $e->getMessage());
}


/app/environments/dev/common/config/main-local.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
 
use yii\db\ActiveQuery;
use yii\db\Connection;
use yii\symfonymailer\Mailer;
 
if ( !function_exists('printPre') )
{
    function printPre($data, bool $exit = true): void
    {
        if(!is_array($data) AND !is_object($data)) $data = [$data];
 
        echo '<pre>';
        print_r($data);
        if ($exit) exit('</pre>');
 
        echo '</pre>';
    }
 
    function printPreSql(ActiveQuery $query): void
    {
        printPre($query->createCommand()->rawSql);
    }
}
 
return [
    'components' => [
        'db' => [
            'class' => Connection::class,
            'dsn' => $_ENV['DB_DSN_LOCAL'],
            'username' => $_ENV['DB_USER'],
            'password' => $_ENV['DB_PASS'],
            'charset' => 'utf8',
        ],
        'mailer' => [
            'class' => Mailer::class,
            'viewPath' => '@common/mail',
            'useFileTransport' => $_ENV['MAILER_FAKE'],
            'transport' => [
                'scheme' => 'smtps',
                'host' => $_ENV['MAILER_HOST'],
                'username' => $_ENV['MAILER_USERNAME'],
                'password' => $_ENV['MAILER_PASSWORD'],
                'port' => $_ENV['MAILER_PORT'],
                'dsn' => $_ENV['MAILER_DSN'],
            ],
        ],
    ],
];

/app/environments/dev/common/config/test-local.php

PHP
1
2
3
4
5
6
7
8
9
<?php
 
return [
    'components' => [
        'db' => [
            'dsn' => $_ENV['DB_DSN_TESTS'],
        ],
    ],
];


/app/environments/dev/frontend/web/index.php
PHP
1
2
3
4
5
6
7
<?php
 
// frontend index.php
 
defined('YII_CONTEXT') or define('YII_CONTEXT', 'frontend');
 
require __DIR__.'/../../endpoint.php';

/app/environments/dev/frontend/web/index-test.php
PHP
1
2
3
4
5
6
7
<?php
 
// frontend index.php
 
defined('YII_CONTEXT') or define('YII_CONTEXT', 'frontend');
 
require __DIR__.'/../../endpoint-test.php';


/app/environments/dev/backend/web/index.php
PHP
1
2
3
4
5
6
7
<?php
 
// Back-end index.php
 
defined('YII_CONTEXT') or define('YII_CONTEXT', 'backend');
 
require __DIR__.'/../../endpoint.php';

/app/environments/dev/backend/web/index-test.php
PHP
1
2
3
4
5
6
7
<?php
 
// backend index-test.php
 
defined('YII_CONTEXT') or define('YII_CONTEXT', 'backend');
 
require __DIR__.'/../../endpoint-test.php';



/app/environments/prod


/app/environments/prod/yii.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/env php
<?php
/**
 * Yii console bootstrap file.
 */
 
use Dotenv\Dotenv;
use yii\base\InvalidConfigException;
use yii\console\Application;
 
try
{
    defined('YII_DEBUG') or define('YII_DEBUG', false);
    defined('YII_ENV') or define('YII_ENV', 'prod');
    defined('PATH_APP') or define('PATH_APP', __DIR__ . '/app/');
 
    require __DIR__ . '/vendor/autoload.php';
    require __DIR__ . '/vendor/yiisoft/yii2/Yii.php';
    require PATH_APP. 'common/config/bootstrap.php';
    require PATH_APP. 'console/config/bootstrap.php';
 
    Dotenv::createImmutable(__DIR__,'.env')->load();
 
    $config = yii\helpers\ArrayHelper::merge(
        require PATH_APP. 'common/config/main.php',
        require PATH_APP. 'common/config/main-local.php',
        require PATH_APP. 'console/config/main.php',
        require PATH_APP. 'console/config/main-local.php'
    );
 
    $application = new Application($config);
 
    $exitCode = $application->run();
 
    exit($exitCode);
 
} catch (InvalidConfigException $e) {
 
    exit('Fatality:' . $e->getMessage());
}


/app/environments/prod/frontend/web/index.php
PHP
1
2
3
4
5
6
7
<?php
 
// frontend index.php
 
defined('YII_CONTEXT') or define('YII_CONTEXT', 'frontend');
 
require __DIR__.'/../../endpoint.php';


/app/environments/prod/backend/web/index.php
PHP
1
2
3
4
5
6
7
<?php
 
// Back-end index.php
 
defined('YII_CONTEXT') or define('YII_CONTEXT', 'backend');
 
require __DIR__.'/../../endpoint.php';




--------------------

/init.php:16
Правка в путях
PHP
1
$root = str_replace('\\', '/', __DIR__);
->
PHP
1
$root = str_replace('\\', '/', __DIR__) . '/app';
PHP
1
file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
->
PHP
1
2
3
    $content = file_get_contents($root . '/' . $source);
    if (str_contains($target, 'yii')) $root = "$root/..";
    file_put_contents($root . '/' . $target, $content);
Настройка сервера.
Apache(OS)

Создание файлов в корне проекта


.htaccess
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On
</IfModule>
 
<IfModule mod_rewrite.c>
 
    RewriteCond %{HTTP_HOST} ^/(upload)
        RewriteRule ^upload/(.*)$ upload/$1 [L]
 
    # если /svg, то в svg
    RewriteCond %{REQUEST_URI} ^/(static)
        RewriteRule ^static/(.*)$ static/$1 [L]
 
    # если /admin, то в backend
    RewriteCond %{REQUEST_URI} ^/(admin)
        RewriteRule ^admin/assets/(.*)$ app/backend/web/assets/$1 [L]
        RewriteRule ^admin/images/(.*)$ app/backend/web/images/$1 [L]
        RewriteRule ^admin/css/(.*)$ app/backend/web/css/$1 [L]
        RewriteRule ^admin/js/(.*)$ app/backend/web/js/$1 [L]
 
    RewriteCond %{REQUEST_URI} !^/backend/web/(assets|js|css|js)/
    RewriteCond %{REQUEST_URI} ^/(admin)
        RewriteRule ^.*$ app/backend/web/index.php [L]
 
    RewriteCond %{REQUEST_URI} ^/(assets|css|js|images|fonts)
        RewriteRule ^assets/(.*)$ app/frontend/web/assets/$1 [L]
        RewriteRule ^images/(.*)$ app/frontend/web/images/$1 [L]
        RewriteRule ^css/(.*)$ app/frontend/web/css/$1 [L]
        RewriteRule ^js/(.*)$ app/frontend/web/js/$1 [L]
        RewriteRule ^(.*)$ app/frontend/web/$1 [L]
 
    RewriteCond %{REQUEST_URI} !^/(frontend|backend)/web/(assets|css|js)/
    RewriteCond %{REQUEST_URI} !index.php
    RewriteCond %{REQUEST_FILENAME} !-f [OR]
    RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^.*$ app/frontend/web/index.php
 
</IfModule>
 
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>

/app/backend/web/.htaccess
PHP
1
2
3
4
5
6
7
8
RewriteEngine on
 
# если это папка или файл, открываем его
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
 
# в противном случае перенаправляем на index.php
RewriteRule . index.php

/app/frontend/web/.htaccess
PHP
1
2
3
4
5
6
7
8
RewriteEngine on
 
# если это папка или файл, открываем его
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
 
# в противном случае перенаправляем на index.php
RewriteRule . index.php




Migration
Создание файлов для миграций:

Создание компонентов миграций

/app/console/components/migrations/Migration
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
 
namespace console\components\migrations;
 
use yii\console\ExitCode;
use yii\db\Exception;
 
/**
 *
 */
abstract class Migration extends \yii\db\Migration
{
    /** @var string  */
    public const TABLE_NAME = '';
 
    /** @var array  */
    public const FOREIGN_KEYS = [];
 
    /** @var bool  */
    public const DELETE_TABLE = true;
 
 
 
    /**
     * @param $table
     * @param $columns
     * @param $options
     *
     * @return void
     */
    public function createTable($table, $columns, $options = null): void
    {
        // https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
        $tableOptions = ($this->db->driverName === 'mysql')
            ? 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'
            : null;
 
        parent::createTable($table, $columns, $tableOptions);
 
        $this->setupForeignKey();
    }
 
    /**
     * @return int
     */
    public function safeDown(): int
    {
        try {
 
            $this->dropForeignKeyList();
 
            if (static::DELETE_TABLE) $this->dropTable(self::TABLE_NAME );
 
        } catch ( Exception $e ) {
 
            echo $e->getMessage();
 
            return ExitCode::DATAERR;
        }
 
        return ExitCode::OK;
    }
 
    /**
     * @return void
     */
    public function setupForeignKey(): void
    {
        foreach (static::FOREIGN_KEYS as $fk_data )
            call_user_func_array(array($this, 'addForeignKey'), $fk_data);
    }
 
    /**
     * @return void
     */
    public function dropForeignKeyList(): void
    {
        foreach (static::FOREIGN_KEYS as $fk_data )
            $this->dropForeignKey($fk_data[0],$fk_data[1]);
    }
}


Далее не обязательные компоненты, которые можно добавить в процессе.

/app/console/components/migrations/MigrationAddColumn.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
 
namespace console\components\migrations;
 
use yii\console\ExitCode;
 
/**
 *
 */
abstract class MigrationAddColumn extends Migration
{
    /** @var string  */
    public string $columnName = '';
 
 
    /**
     * @param $table
     * @param $column
     * @param $type
     *
     * @return void
     */
    public function addColumn($table, $column, $type): void
    {
        parent::addColumn($table, $column, $type);
 
        $this->setupForeignKey();
    }
 
    /**
     * @return int
     */
    public function safeDown(): int
    {
        $this->dropForeignKeyList();
 
        $this->dropColumn(self::TABLE_NAME, $this->columnName );
 
        return ExitCode::OK;
    }
}

/app/console/components/migrations/MigrationAlterColumn.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
 
namespace console\components\migrations;
 
use yii\console\ExitCode;
 
/**
 *
 */
abstract class MigrationAlterColumn extends Migration
{
    /** @var string  */
    public string $columnName = '';
 
 
    /**
     * @param $table
     * @param $column
     * @param $type
     *
     * @return void
     */
    public function alterColumn($table, $column, $type): void
    {
        parent::alterColumn($table, $column, $type);
 
        $this->setupForeignKey();
    }
 
    /**
     * @return int
     */
    public function safeDown(): int
    {
        $this->dropForeignKeyList();
 
        return ExitCode::OK;
    }
}

/app/console/components/migrations/MigrationRemoveColumn.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
 
namespace console\components\migrations;
 
use yii\console\ExitCode;
use yii\db\ColumnSchemaBuilder;
 
/**
 *
 */
abstract class MigrationRemoveColumn extends Migration
{
    /** @var string  */
    public string $columnName = '';
 
    /**
     * @param $table
     * @param $column
     * @param $type
     *
     * @return void
     */
    public function alterColumn($table, $column, $type): void
    {
        parent::alterColumn($table, $column, $type);
 
        $this->setupForeignKey();
    }
 
    /**
     * @return int
     */
    public function safeDown(): int
    {
        $this->dropForeignKeyList();
 
        $this->addColumn(self::TABLE_NAME,$this->columnName, $this->getColumnSchema());
 
        return ExitCode::OK;
    }
 
    /**
     * @return ColumnSchemaBuilder
     */
    abstract public function getColumnSchema(): ColumnSchemaBuilder;
}



update migrate
/app/console/migrations/m123456_123456_init.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
use yii\console\ExitCode;
use console\components\migration\Migration;
 
/**
 *
 */
class m123456_123456_init extends Migration
{
    /** @var string  */
    public const TABLE_NAME = '{{%user}}';
 
    /**
     * @return int
     */
    public function safeUp(): int
    {
        $this->createTable(self::TABLE_NAME, [
            'id' => $this->primaryKey(),
            'status' => $this->smallInteger()->notNull()->defaultValue(10),
            'username' => $this->string()->notNull()->unique(),
            'email' => $this->string()->notNull()->unique(),
            'auth_key' => $this->string(32)->notNull(),
            'password_hash' => $this->string()->notNull(),
            'password_reset_token' => $this->string()->unique(),
            'verification_token' => $this->string()->defaultValue(null),
            'created_at' => $this->dateTime()->notNull(),
            'updated_at' => $this->dateTime()->notNull(),
        ]);
 
        return ExitCode::OK;
    }
}



Base Elements

Создание обязательных базовых компонентов

Модель.
/app/common/components/models/BaseModel
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
 
namespace common\components\models;
 
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
 
/**
 * Базовый класс моделей
 */
class BaseModel extends ActiveRecord
{
    /**
     * Поведения
     * 
     * @return array
     */
    public function behaviors(): array
    {
        return [
            [
                'class' => TimestampBehavior::class,
                'value' => date('Y-m-d H:i:s')
            ]
        ];
    }
 
    /**
     * Получение списка ID. 
     *      Опционально передаётся условие
     * 
     * @param mixed $criteria
     *
     * @return array
     */
    public static function  getIdList(mixed $criteria = null): array
    {
        return static::getColumn('id', $criteria);
    }
 
    /**
     * Получение массива указанной колонки.
     *      Опционально передаётся условие
     * 
     * @param string $column
     * @param mixed|null $criteria
     *
     * @return array
     */
    public static function getColumn(string $column, mixed $criteria = []): array
    {
        //Запрос
        $query = static::find()->select($column)->where($criteria);
 
        // Результат запроса
        return $query->column();
    }
 
    /**
     * Получение `Map` массива из двух значений.
     *      Для формирования DropDown списка
     * 
     * @param string $key
     * @param string $label
     * @param mixed|null $criteria
     *
     * @return array
     */
    public static function getMap(string $key, string $label, array $criteria = []): array
    {
        // Запрос
        $query = self::find()->select("$key,$label")->where($criteria);
        
        // Результат запроса
        return $query->asArray()->all();
    }
}


Ресурсы
/app/common/components/resources/BaseResources
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
 
namespace common\components\resources;
 
/**
 *  Базовый класс для ресурсов.
 *      Раздаёт функционал всем ресурсам
 */
class BaseResources
{
    /** 
     * @var string Ключ по которому в шаблоне будет доступен ресурс 
     * 
     * 
     * @example
     * 
     * use frontend\components\resources\UserIndexResource;
     * 
     * var  UserIndexResource $R
     * 
     * if ( $R->model->isNewRecord) {
     *      ...
     */
    public const KEY = 'R';
 
    /**
     * Получение ключевого массива для передачи его в качестве параметров в шаблон
     * 
     * public function actionView(int $id)
     * {
     *      $R = new UserViewResource();
     *      $R->project = $this->serviceProject->findByID($id);
     * 
     *      return $this->render(UserViewResource::TEMPLATE, $R->release() )
     * }
     * 
     * @return BaseResources[]
     */
    public function release(array $params = [] ): array
    {
        return array_merge($params,[ static::KEY => $this ]);
    }
}


Сервисы.
/app/common/components/services/BaseService
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
 
namespace common\components\services;
 
use yii\helpers\ArrayHelper;
use common\components\models\BaseModel;
 
/**
 *  Базовый класс для сервисов.
 *      Раздаёт функционал всем сервисам
 */
class BaseService
{
    /** @var BaseModel Модель используемая в сервисе */
    public const MODEL_CLASS = BaseModel::class;
 
 
 
    /**
     * Создание модели runtime в памяти/окружении
     *
     * @param $attr
     * @param ?string $className
     *
     * @return BaseModel
     */
    public function createModel($attr, ?string $className = null): BaseModel
    {
        /** @var BaseModel $model */
        $model = new ( $className ?? static::MODEL_CLASS)();
 
        $model->setAttributes($attr);
 
        return $model;
    }
 
    /**
     * Создание модели в базе данных
     *
     * @param $attr
     * @param string|null $className
     *
     * @return BaseModel
     */
    public function add($attr, ?string $className = null): BaseModel
    {
        $model = $this->createModel($attr, $className);
 
        $model->save();
 
        return $model;
    }
 
    /**
     * Получение ID всех существующих моделей
     *
     * @param array $criteria
     *
     * @return array
     */
    public function getAllId(array $criteria = []): array
    {
        return (static::MODEL_CLASS)::getIdList($criteria);
    }
 
    /**
     * получение dropDown писка
     *
     * @param string $key
     * @param string $value
     * @param array $criteria
     *
     * @return array
     */
    public function getDropDown(string $key, string $value, array $criteria = []): array
    {
        $data = (static::MODEL_CLASS)::getMap($key, $value, $criteria);
 
        return ArrayHelper::map($data,$key, $value);
    }
}



__________


Console

Удаляю файл `composer.lock`

console

Выполняю в консоли команду: `composer require vlucas/phpdotenv`

Code
1
2
3
4
5
6
7
8
9
composer install
 
composer update
 
init
 
php yii migrate
 
php yii_test migrate
transfer
переношу файлы(yii.php, yii.bat, yii_test.php ) из директории `app` в корень проекта.


____________________

генерация файлов для работы с моделями
генерация файлов для работы с моделью `User`

для остальных моделей принцип тот же.

Создание директории для сгенерированных моделей `app/common/models/items`;

Переходим в раздел `gii`, генерируем модель
  • Table Name: user
  • Model Class Name: UserSource
  • Namespace: common\models\items
  • Base Class: common\components\models\BaseModel

Создание "боевой" common модели:
/app/common/models/items/User.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
 
namespace common\models\items;
 
use \common\models\User as CommonUser;
 
/**
 * "Боевая" common модель `User`.
 */
class User extends UserSource
{
    /** @var array  */
    public const STATUS_LIST = [
        CommonUser::STATUS_ACTIVE,
        CommonUser::STATUS_INACTIVE,
        CommonUser::STATUS_DELETED,
    ];
}


Создание "консольной" формы для модели пользователь:
/app/console/models/forms/UserForm.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
 
namespace console\models\forms;
 
use common\models\items\User;
 
/**
 * Форма пользователя для создания через CLI
 */
class UserForm extends User
{
    /**
     * {@inheritdoc}
     */
    public function rules(): array
    {
        return [
            [['status'], 'integer'],
            [['username', 'email', 'auth_key', 'password_hash'], 'required'],
            [['created_at', 'updated_at'], 'safe'],
            [['username', 'email', 'password_hash'], 'string', 'max' => 255],
            [['auth_key'], 'string', 'max' => 32],
            [['username', 'email'], 'unique'],
        ];
    }
}


Создание общего сервиса
/app/common/services/UserService.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
 
namespace common\services;
 
use common\models\items\User;
use common\components\services\BaseService;
 
/**
 * Общий сервис для модели `User`
 *
 * @method User createModel($attr)
 * @method User add($attr)
 */
class UserService extends BaseService
{
    public const MODEL_CLASS = User::class;
 
    /**
     * @return array
     */
    public function getUserStatusList(): array
    {
        return User::STATUS_LIST;
    }
}


Создание консольного сервиса
/app/console/services/UserService.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
 
namespace console\services;
 
use console\models\forms\UserForm;
 
/**
 * @method UserForm createModel($attr)
 * @method UserForm add($attr)
 */
class UserService extends \common\services\UserService
{
    /** @var string  */
    public const MODEL_CLASS = UserForm::class;
}


Создание консольного контроллера
/app/console/controllers/UserController.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
 
namespace console\controllers;
 
use Yii;
use yii\base\Exception;
use yii\console\Controller;
use yii\helpers\BaseConsole;
use common\models\User;
use console\services\UserService;
 
/**
 *
 */
class UserController extends Controller
{
    /** @var UserService  */
    private UserService $service;
 
 
 
    /**
     * @return void
     */
    public function init(): void
    {
        parent::init();
 
        $this->service = new UserService();
    }
 
    /**
     * @return void
     *
     * @throws Exception
     */
    public function actionAdd(): void
    {
        $statusList = $this->service->getUserStatusList();
 
        $username = $this->getUsername();
        $password = $this->getPassword();
 
        $email = $this->prompt('Email : ');
        $status = $this->prompt('Status ('.implode(',',$statusList).') : ');
 
        $this->create($username, $email, $password, (int) $status);
    }
 
    /**
     * @return void
     *
     * @throws Exception
     */
    public function actionCreateAdmin(): void
    {
        $username = $this->getUsername();
        $password = $this->getPassword();
 
        $this->create($username, "$username@local.dev", $password, User::STATUS_ACTIVE );
    }
 
    /**
     * @param string $username
     * @param string $email
     * @param string $password
     * @param int $status
     *
     * @return void
     *
     * @throws Exception
     */
    private function create(string $username, string $email, string $password, int $status): void
    {
        echo "User `$username` : ";
 
        $userData = [
            'username' => $username,
            'email' => $email,
            'auth_key' => md5(time()),
            'status' => $status,
            'password_hash' => Yii::$app->security->generatePasswordHash($password),
        ];
 
        $user = $this->service->createModel($userData);
 
        $user->save();
 
        if ( $user->hasErrors() )
        {
            echo $this->ansiFormat('created error:', BaseConsole::FG_RED);
 
            print_r($user->errors);
            die;
 
        } else {
 
            echo $this->ansiFormat('created success', BaseConsole::FG_GREEN);
        }
 
 
    }
 
    /**
     * @return string
     */
    private function getUsername(): string
    {
        return $this->prompt('username : ');
    }
 
    /**
     * @return string
     */
    private function getPassword(): string
    {
        return $this->prompt('password : ');
    }
 
 
    
    /**
     * Для устранения notice: Unused element: 'actionName'
     * 
     * @throws Exception
     */
    public function __actions()
    {
        $this->actionAdd();
        
        $this->actionCreateAdmin();
    }
}


Создание вспомогательного файла `__autocomplete.php`
/app/console/config/__autocomplete.php
PHP
1
2
3
4
5
6
7
8
9
10
<?php
 
use console\controllers\UserController;
 
/**
 * Устранение notice: Unused element: 'NameController'
 */
$controllerList = [
    UserController::class
];



console
Code
1
2
3
php yii user/create-admin
username :  admin
password :  123123123
Миниатюры
Нажмите на изображение для увеличения
Название: yii2_structure.jpg
Просмотров: 365
Размер:	409.0 Кб
ID:	8143  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru