Difference between #93 and #110 of
Yii v2 snippet guide III

Changes

Title unchanged

Yii v2 snippet guide III

Category unchanged

Tutorials

Yii version unchanged

2.0

Tags unchanged

tutorial,yii2,beginer

Content changed

[...]
HelloWidget::begin(['message' => ' Yii2.0']);
echo 'My content';
HelloWidget::end();
```

**Tests - unit +
opa**
 
---
 
It is easy to run tests as both demo-applications are ready. Use command line and navigate to your project. Then type:
 
 
```php
 
php ./vendor/bin/codecept run
 
```
 
 
This will run Unit and Functional tests. They are defined in folder tests/unit and tests/functional. Functional tests run in a hidden browser and do not work with JavaScript I think. In order to test complex JavaScript, you need Acceptance Tests. How to run them is to be found in file README.md or in [documentation](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing) in both demo applications. If you want to run these tests in your standard Chrome or Firefox browser, you will need [Java JDK](https://www.oracle.com/java/technologies/downloads/) and file [selenium-server*.jar](https://www.selenium.dev/downloads). See links in README.md. Once you have the JAR file, place is to your project and run it:
 
 
```php
 
java -jar selenium-server-4.0.0.jar standalone
 
```
 
 
Now you can rerun your tests. Make sure that you have working URL of your project in file acceptance.suite.yml, section WebDriver. For example http://localhost/yii-basic/web. It depends on your environment. Also specify browser. For me works well setting "browser: chrome".
 
If you receive error "WebDriver is not installed", you need to call this composer command:
 
 
```php
 
composer require codeception/module-webdriver --dev
 
```
 
 
PS: There is also this file [ChromeDriver](https://chromedriver.chromium.org/downloads) but I am not really sure if it is an alternative to "codeception/module-webdriver" or when to use it. I havent studied it yet.
functional + acceptance (opa) + coverage**
 
---
 
It is easy to run tests as both demo-applications are ready. Use command line and navigate to your project. Then type:
 
 
```php
 
php ./vendor/bin/codecept run
 
```
 
 
This will run Unit and Functional tests. They are defined in folder tests/unit and tests/functional. Functional tests run in a hidden browser and do not work with JavaScript I think. In order to test complex JavaScript, you need Acceptance Tests. How to run them is to be found in file README.md or in [documentation](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing) in both demo applications. If you want to run these tests in your standard Chrome or Firefox browser, you will need [Java JDK](https://www.oracle.com/java/technologies/downloads/) and file [selenium-server*.jar](https://www.selenium.dev/downloads). See links in README.md. Once you have the JAR file, place is to your project and run it:
 
 
```php
 
java -jar selenium-server-4.0.0.jar standalone
 
```
 
 
Now you can rerun your tests. Make sure that you have working URL of your project in file acceptance.suite.yml, section WebDriver. For example http://localhost/yii-basic/web. It depends on your environment. Also specify browser. For me works well setting "browser: chrome".
 
If you receive error "WebDriver is not installed", you need to call this composer command:
 
 
```php
 
composer require codeception/module-webdriver --dev
 
```
 
 
PS: There is also this file [ChromeDriver](https://chromedriver.chromium.org/downloads) but I am not really sure if it is an alternative to "codeception/module-webdriver" or when to use it. I havent studied it yet.
 
 
If you want to see the code coverage, do what is described in the documentation (link above). Plus make sure that your PHP contains [xDebug](https://gist.github.com/odan/1abe76d373a9cbb15bed)! And mind the difference in settings of xDebug2 and xDebug3! If xDebug is missing, you will receive error "No code coverage driver available".
 
 
**Microsoft Access MDB**
 
---
 
Under Linux I haven't suceeded, but when I install a web server on Windows (for example XAMPP Server) I am able to install "Microsoft Access Database Engine 2016 Redistributable" and use *.mdb file.
 
 
So first of all you should install the web server with PHP and you should know wheather you are installing 64 or 32bit versions. Probably 64. Then go to page [Microsoft Access Database Engine 2016 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=54920) (or find newer if available) and install corresponding package (32 vs 64bit). 
 
 
Note: If you already have MS Access installed in the identical bit-version, you might not need to install the engine.
 
 
Then you will be able to use following DSN string in DB connection. (The code belongs to file config/db.php):
 
 
```
 
<?php
 
 
$file = "C:\\xampp\\htdocs\\Database1.mdb";
 
 
return [
 
  'class' => 'yii\db\Connection',
 

 
  'dsn' => "odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=$file;Uid=;Pwd=;",
 
  'username' => '',
 
  'password' => '',
 
  'charset' => 'utf8',
 

 
  //'schemaMap' => [
 
  //  'odbc'=> [
 
  //    'class'=>'yii\db\pgsql\Schema',
 
  //    'defaultSchema' => 'public' //specify your schema here
 
  //  ]
 
  //], 
 
 
  // Schema cache options (for production environment)
 
  //'enableSchemaCache' => true,
 
  //'schemaCacheDuration' => 60,
 
  //'schemaCache' => 'cache',
 
];
 
```
 
 
Then use this to query a table:
 
 
```
 
$data = Yii::$app->db->createCommand("SELECT * FROM TableX")->queryAll();
 
var_dump($data);
 
```
 
 
Note: If you already have MS Access installed in different bit-version then your PHP, you will not be able to install the engine in the correct bit-version. You must uninstall MS Access in that case.
 
 
Note2: If you do not know what your MDB file contains, Google Docs recommended me [MDB, ACCDB Viewer and Reader](https://mdbviewer.herokuapp.com) and it worked.
 
 
Note3: There are preinstalled applications in Windows 10 named:
 
- "ODBC Data Sources 32-bit"
 
- "ODBC Data Sources 64-bit"
 
- (Just hit the Win-key and type "ODBC")
 
 
Open the one you need, go to tab "System DSN" and click "Add". You will see what drivers are available - **only these drivers can be used in the DSN String!!**
 
 
If only "SQL Server" is present, then you need to install the Access Engine (or MS Access) with drivers for your platform. You need driver named cca "Microsoft Access Driver (\*.mdb, \*.accdb)"
 
 
In my case the Engine added following 64bit drivers:
 
- Microsoft Access dBASE Driver (\*.dbf, \*.ndx, \*.mdx)
 
- Microsoft Access Driver (\*.mdb, \*.accdb)
 
- Microsoft Access Text Driver (\*.txt, \*.csv)
 
- Microsoft Excel Driver (\*.xls, \*.xlsx, \*.xlsm, \*.xlsb)
 
 
**And how about Linux ?**
 
 
You need the MS Access Drivers as well, but Microsoft does not provide them. There are some 3rd party [MdbTools](https://github.com/mdbtools/mdbtools) or [EasySoft](https://www.easysoft.com/products/data_access/odbc-access-driver/index.html#section=tab-1), but their are either not-perfect or expensive. Plus there is [Unix ODBC](http://www.unixodbc.org/). 
 
 
For Java there are [Java JDBC](http://www.hxtt.com/access.html), [Jackcess](https://jackcess.sourceforge.io/) and [Ucanaccess](http://ucanaccess.sourceforge.net/site.html).
 
 
**And how about Docker ?**
 
As far as I know you cannot run Windows images under Linux so you will not be able to use the ODBC-advantage of Windows in this case.
 
You can use Linux images under Windows, but I think there is no way how to access the ODBC drivers from virtual Linux. You would have to try it, I haven't tested it yet.
 
 
**Migration batch insert csv**
 
---
 
 
If you want to import CSV into your DB in Yii2 migrations, you can create this "migration base class" and use it as a parent of your actual migration. Then you can use method batchInsertCsv().
 
 
```php
 
<?php
 
 
namespace app\components;
 
 
use yii\db\Migration;
 
 
class BaseMigration extends Migration
 
{
 
    /**
 
     * @param $filename Example: DIR_ROOT . DIRECTORY_SEPARATOR . "file.csv"
 
     * @param $table The target table name
 
     * @param $csvToSqlColMapping [csvColName => sqlColName] (if $containsHeaderRow = true) or [csvColIndex => sqlColName] (if $containsHeaderRow = false)
 
     * @param bool $containsHeaderRow If the header with CSV col names is present
 
     * @param int $batchSize How many rows will be inserted in each batch
 
     * @throws Exception
 
     */
 
    public function batchInsertCsv($filename, $table, $csvToSqlColMapping, $containsHeaderRow = false, $batchSize = 10000, $separator = ';')
 
    {
 
        if (!file_exists($filename)) {
 
            throw new \Exception("File " . $filename . " not found");
 
        }
 
 
        // If you see number 1 in first inserted row and column, most likely BOM causes this.
 
        // Some Textfiles begin with 239 187 191 (EF BB BF in hex)
 
        // bite order mark https://en.wikipedia.org/wiki/Byte_order_mark
 
        // Let's trim it on the first row.
 
        $bom = pack('H*', 'EFBBBF');
 
 
        $handle = fopen($filename, "r");
 
        $lineNumber = 1;
 
        $header = [];
 
        $rows = [];
 
        $sqlColNames = array_values($csvToSqlColMapping);
 
        $batch = 0;
 
 
        if ($containsHeaderRow) {
 
            if (($raw_string = fgets($handle)) !== false) {
 
                $header = str_getcsv(trim($raw_string, $bom), $separator);
 
            }
 
        }
 
 
        // Iterate over every line of the file
 
        while (($raw_string = fgets($handle)) !== false) {
 
            $dataArray = str_getcsv(trim($raw_string, $bom), $separator);
 
 
            if ($containsHeaderRow) {
 
                $dataArray = array_combine($header, $dataArray);
 
            }
 
 
            $tmp = [];
 
            foreach ($csvToSqlColMapping as $csvCol => $sqlCol) {
 
                $tmp[] = trim($dataArray[$csvCol]);
 
            }
 
            $rows[] = $tmp;
 
 
            $lineNumber++;
 
            $batch++;
 
 
            if ($batch >= $batchSize) {
 
                $this->batchInsert($table, $sqlColNames, $rows);
 
                $rows = [];
 
                $batch = 0;
 
            }
 
        }
 
        fclose($handle);
 
 
        $this->batchInsert($table, $sqlColNames, $rows);
 
    }
 
}
 
```
 
8 0
4 followers
Viewed: 164 820 times
Version: 2.0
Category: Tutorials
Written by: rackycz
Last updated by: rackycz
Created on: Jan 21, 2021
Last updated: 9 months ago
Update Article

Revisions

View all history