Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) using rbac

I am using rbac for setting permissions to each user and check permission for each action using if Yii::$app->user->can() method.

For example, if (Yii::$app->user->can(‘View-all-Inventory’))

This was working properly until I recently added 2 new permissions in auth-item DB table and allotted them to parent Super-Administrator.

After this, I suddenly started getting following fatal error:

Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) using rbac

I checked and applied many solutions for this, but this error remains as it. I can see this error on my localhost using xampp and also at live server.

I have increased memory limit to 256M and further increased upto 512M. Still I am getting same error. I disabled Yii2 debugger and set environment to LIVE. Still it didnot help. I was getting error in getChildrenRecursive function with logger. Further debugging, I found that when I comment code inside public function checkAccess and simply return true, everything seems to be working as before with no more errors. Commenting this is temporary solution, but i had to this on LIVE server to avoid errors on LIVE site.

But, I think the issue is with recursive function checkAccessRecursive. It is being recursively called many times which causes memory limit to exhaust. Can you please suggest how to optimize this function , I have only 2 level of hierarchy i.e one parent has many children but any child donot have further children.

I am struck and not sure how to sort this and allow access using permissions.

Please help.

Thanks in Advance!

Did you maybe create a recursion in your RBAC history by mistake? Same item as parent and child?

Wrong sub-forum, by the way.

No , there are only 134 records in tblauth_item_child table. I have different parent names like admin, manager etc and completely different children name like edit-profile, view-inventory etc. So, same item and same child cannot be there.

I debugged a little and found the error occurs when this part of function is executed in protected function checkAccessRecursive { }

$query = new Query;

    $parents = $query->select(['parent'])


        ->from($this->itemChildTable)


        ->where(['child' => $itemName])


        ->column($this->db);


    foreach ($parents as $parent) {


        if ($this->checkAccessRecursive($user, $parent, $params, $assignments)) {


            return true;


        }


    }

When i comment this and add this code, this error is resolved.

foreach ($assignments as $a) {

		//echo "<pre>";


        //print_r($a);


		$roleName = $a->roleName;


		$res = Yii::$app->db->createCommand("SELECT * FROM `tblauth_item_child` WHERE `parent` = '".$roleName."' AND `child` LIKE '".$itemName."'");


		


		if ($res){


			return true;


			exit;


		} 


	}

But I am getting errors in other function like:

Calling unknown method: yii\rbac\DbManager::getItems()

Thanks

Both this recursive functions are causing memory limit when we check permission for each action in controller.

/**

 * Performs access check for the specified user.


 * This method is internally called by [[checkAccess()]].


 * @param string|integer $user the user ID. This should can be either an integer or a string representing


 * the unique identifier of a user. See [[\yii\web\User::id]].


 * @param string $itemName the name of the operation that need access check


 * @param array $params name-value pairs that would be passed to rules associated


 * with the tasks and roles assigned to the user. A param with name 'user' is added to this array,


 * which holds the value of `$userId`.


 * @param Assignment[] $assignments the assignments to the specified user


 * @return boolean whether the operations can be performed by the user.


 */


protected function checkAccessRecursive($user, $itemName, $params, $assignments)


{


	


    if (($item = $this->getItem($itemName)) === null) {


        return false;


    }





    Yii::trace($item instanceof Role ? "Checking role: $itemName" : "Checking permission: $itemName", __METHOD__);





    if (!$this->executeRule($user, $item, $params)) {


        return false;


    }





    if (isset($assignments[$itemName]) || in_array($itemName, $this->defaultRoles)) {


        return true;


    }





    $query = new Query;


    $parents = $query->select(['parent'])


        ->from($this->itemChildTable)


        ->where(['child' => $itemName])


        ->column($this->db);


    foreach ($parents as $parent) {


        if ($this->checkAccessRecursive($user, $parent, $params, $assignments)) {


            return true;


        }


    }





    return false;


}

/**

 * Recursively finds all children and grand children of the specified item.


 * @param string $name the name of the item whose children are to be looked for.


 * @param array $childrenList the child list built via [[getChildrenList()]]


 * @param array $result the children and grand children (in array keys)


 */


protected function getChildrenRecursive($name, $childrenList, &$result)


{		


    if (isset($childrenList[$name])) {


        foreach ($childrenList[$name] as $child) {


            $result[$child] = true;


            $this->getChildrenRecursive($child, $childrenList, $result);


        }


    } 


	


}

May be they are getting into never ending loops which causes memory limit error.