Приведение к типам в Yii::app()->request

в 7:49, , рубрики: mongodb, mysql, php, yii, метки: , , ,

Всем привет!

Хочу поделиться с вами небольшим решением проблемы, с которой столкнулся при переносе части данных проекта в mongodb.
Изначально у нас использовалась только Mysql и все параметры приходящие от клиента вполне себе позволяли получать данные из базы без каких-либо проблем.

<?php
   $id = Yii::app()->request->getParam('id', 0);
   $data = Data::getForId($id);
?>

А суть в том, что для mysql нет разницы [select * from data where id = 1] или [select * from data where '1'].
Но mongodb типы данных различает, по этому нельзя найти запись используя условие id == '1' если id в mongodb является числом.

Для того, чтобы не усложнять и не увеличивать количество кода за счет добавления (int) для приведения типа

<?php
   $id = (int)Yii::app()->request->getParam('id', 0);
?>

было выбрано седующее решение — создание собственного request менеджера на основе стандартного CHttpRequest.
Получился следующий класс

<?php

class CParseRequest extends CHttpRequest
{
	public function getParam($name,$defaultValue=null)
	{
		$data = parent::getParam($name, $defaultValue);
		$this->parseData($data);
		return $data;
	}

	public function getQuery($name,$defaultValue=null)
	{
		$data = parent::getQuery($name, $defaultValue);
		$this->parseData($data);
		return $data;
	}

	public function getPost($name,$defaultValue=null)
	{
		$data = parent::getPost($name, $defaultValue);
		$this->parseData($data);
		return $data;
	}

	/**
	 * Функция для приведения типов
	 */
	public function parseData(&$data)
	{
		if (is_array($data)) {
			foreach ($data as &$prop){
				if (is_array($prop)) {
					self::parseData($prop);
				} else {
					if (preg_match("/^[d]+$/", $prop)) $prop = (int)$prop;
				}
			}
		} else {
			if (preg_match("/^[d]+$/", $data)) $data = (int)$data;
		}
	}
}

В настройках следует прописать следующий модуль

	'request' => array(
		'class' => 'CParseRequest'
	),

Теперь полученные данные всегда будут приводиться к нужному типу. Если нам приходит массив любой вложенности, то все его элементы тоже будут приведены к нужным типам.

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

Будет интересно услышать мнение других людей о том, как они решали данную проблему.

Автор: anonimizer_me

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js