Sunday, 12 March 2017

Yii2: PHP Warning - Unable to allocate memory for pool

Yii2 error:

PHP Warning – yii\base\ErrorException

include(): Unable to allocate memory for pool.


* Reason : You have not allocated enough memory for APC cache (file cache or opcode cache)

* Solution 1: Disable APC, If you do not need it (apc.enabled=0)
* Solution 2: Increased memory for APC (apc.shm_size="64")

To do one of the two. Find php.ini or apc.ini on your server. If you do not have admin rights to the server try to use htacess file: php_flag display_errors on


Wednesday, 11 November 2015

Yii2: Get raw SQL Query from an Activerecord or a query builder

This tutorial show you how to dump the Sql Query from an Activerecord and more.
It can help us to debug Sql query in some case when yii debug is not work.

Example:
$listBooks = Books::find()->where('author=2')->all();

To get raw SQL query with all parameters included try:
$query = Books::find()->where('author=2');
echo $query->createCommand()->sql;
echo $query->createCommand()->getRawSql();

It not only works with Activerecord .
Refer : http://chris-backhouse.com/Yii2-Output-the-SQL-from-a-query-builder/1027

Monday, 22 June 2015

Yii2: Unknown Property Exception after adding column to table

Unknown Property – yii\base\UnknownPropertyException
Getting unknown property: app\models

What happens when you get an error Exception "Getting unknown property", after just added a field to the table in the database ?
  1. Check your property name, was it correct?
  2. Clear cache if you using cache. Yii2 will cache the table schema so if you change the table you need to clear the cache

Thursday, 29 January 2015

Yii2: Validate unique if attribute is not empty

Yii2 unique validator, empty string and null is treated the same and ignored. It not the same as mysql when only null value ignored in unique check.
But this is not a bug, not all database management systemare the same with mysql.

So if you want to validate an attribute only when it not empty. Try the following rules :

['phone', 'filter', 'filter' => 'trim'], //trim string
['phone', 'default'], //set null if empty string
['phone', 'unique'],

Refer :
http://www.yiiframework.com/doc-2.0/guide-tutorial-core-validators.html

Tuesday, 27 January 2015

Yii2: Using csrf token

First, if you do not understand what is the CSRF token? and why should we use it, please refer to the following link :
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

One of the new features of Yii2 is CSRF validation enabled by default.
If you use ajax or basic form as follows :

<form action='#' method='POST'>
    ...........
</form>

You will get an error exception :

Bad Request (#400): Unable to verify your data submission

That is because you do not submit csrf token. The easiest way if you dont care about csrf just disable it in main config :

'components' => [
     'request' => [
          ....
          'enableCsrfValidation'=>false,
      ],
      .....
],

Or in Controller :

public function beforeAction($action) {
    $this->enableCsrfValidation = false;
    return parent::beforeAction($action);
}

So how to use Csrf Validation for your strong security website:

* With basic form:
- Create form with yii\widgets\ActiveForm or yii\bootstrap\ActiveForm
ActiveForm will automatically add a token in the form

Can use like this

<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
    <?= $form->field($model, 'username') ?>
    <?= $form->field($model, 'password')->passwordInput() ?>
    ....
<?php ActiveForm::end(); ?>

Or

<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
      <input type='text' name='name'/>
      .........
<?php ActiveForm::end(); ?>

* With manual form:
you must manually add CSRF token in the form

<form action='#' method='POST'>
   <input type="hidden" name="_csrf" value="<?=Yii::$app->request->getCsrfToken()?>" />
   ....
</form>

* With Ajax
- In main layout add csrfMetaTags :
<head>
   .......
   <?= Html::csrfMetaTags() ?>
</head>

- And in javascript ajax code add csrf param like this:

var csrfToken = $('meta[name="csrf-token"]').attr("content");
$.ajax({
         url: 'request',
         type: 'post',
         dataType: 'json',
         data: {param1: param1, _csrf : csrfToken},
});

Monday, 29 December 2014

Yii2: Validate value without model (Ad Hoc Validation)

Sometimes you need to do ad hoc validation for values that are not bound to any model.
If you only need to perform one type of validation (e.g. validating email addresses), you may call the [[yii\validators\Validator::validate()|validate()]] method of the desired validator, like the following:
$email = 'test@example.com';
$validator = new yii\validators\EmailValidator();

if ($validator->validate($email, $error)) {
    echo 'Email is valid.';
} else {
    echo $error;
}
Note: Not all validators support this type of validation. An example is the unique core validator which is designed to work with a model only.
If you need to perform multiple validations against several values, you can use [[yii\base\DynamicModel]] which supports declaring both attributes and rules on the fly. Its usage is like the following:
public function actionSearch($name, $email)
{
    $model = DynamicModel::validateData(compact('name', 'email'), [
        [['name', 'email'], 'string', 'max' => 128],
        ['email', 'email'],
    ]);

    if ($model->hasErrors()) {
        // validation fails
    } else {
        // validation succeeds
    }
}
The [[yii\base\DynamicModel::validateData()]] method creates an instance of DynamicModel, defines the attributes using the given data (name and email in this example), and then calls [[yii\base\Model::validate()]] with the given rules.
Alternatively, you may use the following more "classic" syntax to perform ad hoc data validation:
public function actionSearch($name, $email)
{
    $model = new DynamicModel(compact('name', 'email'));
    $model->addRule(['name', 'email'], 'string', ['max' => 128])
        ->addRule('email', 'email')
        ->validate();

    if ($model->hasErrors()) {
        // validation fails
    } else {
        // validation succeeds
    }
}
After validation, you can check if the validation succeeded or not by calling the [[yii\base\DynamicModel::hasErrors()|hasErrors()]] method, and then get the validation errors from the [[yii\base\DynamicModel::errors|errors]] property, like you do with a normal model. You may also access the dynamic attributes defined through the model instance, e.g., $model->name and $model->email.
Read more : https://github.com/yiisoft/yii2/blob/master/docs/guide/input-validation.md

Monday, 24 November 2014

Yii2: createUrl method

Old Yii1 to create an url we write:

$this->createUrl(); 
or
Yii::app()->createUrl();

Now with Yii2 we have to write

\Yii::$app->getUrlManager()->createUrl(['controler/action','param1'=>'value1','param2'=>'value2']);


Yii2: Error invalid configuration with modules

Error: 
Invalid Configuration – yii\base\InvalidConfigException
The configuration for the "modules" component must contain a "class" element.
Solution: 
Check your config file.  don't put "modules" in component section.
Correct config:
'components'=>[
...
],
'modules'=>[
...
]

Readmore about module : https://github.com/yiisoft/yii2/blob/master/docs/guide/structure-modules.md 

Sunday, 26 October 2014

[MySql] Reset MySQL root password on Linux

1. Login to server as root/su

2. Stop the MySQL service
service mysqld stop
* Note : Be carefully, all your application will be temporarily unable to use mysql.
3. Start MySQL Safe mode with skip grant tables option
mysqld_safe --skip-grant-tables & 
(press ctrl+C to exit, if required)

4. Start the MySQL service
service mysqld start

5. Log into the MySQL server without any password
mysql -u root -p mysql

6. Reset the password for ‘root’ user
UPDATE user SET password=PASSWORD('new-password') where user='root';

7. Flush privileges
flush privileges;

8. Stop MySQL Safe mode
killall mysqld

9. Start the MySQL service again
service mysqld start

10. Try to Log-in with the new password
mysql -u root -p 
<enter new password when prompted>

Friday, 19 September 2014

MySQL: Allowed to remote connect to MySQL server

MySQL Error : Host 'xxx.xx.xxx.xxx' is not allowed to connect to this MySQL server
How to fix it ?

STEP 1: Change mysql config :

vi /etc/mysql/my.cnf
Comment out following lines or edit to your client ip :
#bind-address           = 127.0.0.1
#skip-networking
Restart mysql server:
service mysql restart
STEP 2: Change GRANT privilege :

Login MySQL using command line .
Then run a command like below to grant access for user. Replace 'username' and 'password' with your username and password.
CREATE USER 'username'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' WITH GRANT OPTION;
* '%' mean you can remote access from any ip address, You can replace it with a specified ip address.

Then flush MySQL :
FLUSH PRIVILEGES;

If it's still not working. Let's check your server firewall (iptables ...) and client firewall (windows firewall, antivirus software)