Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Pessoal.. indo direto ao ponto: levando em consideração os tipos de dados do:
PDO :seta: http://php.net/manual/en/pdo.constants.php (PARAM_XXX)
MySQL :seta: char, varchar, binary, varbinary, blob, text, enum, set, date, datetime, timestamp, time, year, int, integer, smallint, decimal, numeric, float, real, double_precision, dec, fixed, bit, etc...
PHP :seta: http://php.net/manual/pt_BR/language.types.php
Como seria a melhor forma de relacionar esses tipos entre si?
Explicando melhor: tenho um array em determinada classe que armazena as informações gerais referentes às tabelas do banco de dados, que seguem este exato padrão:
[ 'tabela' ] => array(
[ 'coluna' ] => 'nome da coluna, em string',
[ 'tipo' ] => 'aqui eu estou em dúvida do que colocar'
), ...
A ideia é que eu possa utilizar essa chave tipo para poder trabalhar NO PHP com os tipos dos diferentes bancos de dados. Exemplo:
Se for string e afins, trato como tipo string no PHP.
Se for datetime, date, etc e tal, trato como classe DateTime do PHP.
Então para fazer um prepared statement do PDO, eu teria que recuperar o tipo no PHP e convertê-lo para a constante apropriada do PDO (para fazer o bindParam / bindValue).
A dúvida é: qual seria o melhor jeito de estruturar toda essa manipulação e relação de tipos nessas diferentes plataformas?
Luis Paullo, obrigado pela contribuição, mas a minha dúvida vai um pouco mais além.. veja:
Se eu fizesse dessa maneira proposta, "[ 'tipo' ] => 'PDO::PARAM_STR', ", haveria uma série de problemas estruturais.
1 - Eu estaria desconsiderando o fato de que uma fonte de dados nem sempre é acessada através do PDO (em outras palavras, eu estaria obrigando minha aplicação a trabalhar somente com PDO).
2 - Para eu utilizar essa constante no bindParam/Value, eu precisaria fazer algo parecido com constant( '\\' . $array[ 'tipo' ] ).
3 - Não estaria considerando os tipos do mysql, que são muitos e diferentes dos demais bancos de dados.
A ideia que eu tive até agora foi de, na minha classe específica de Mysql, eu defino um padrão de tipos e os relaciono com os tipos do mysql, exemplo:
protected static $_dataTypes = array(
'int' => array(
'year', 'int', 'dec', 'numeric', 'fixed', 'bit',
),
'float' => array(
'float', 'real', 'double_precision'
),
'datetime' => array(
'datetime',
),
'timestamp' => array(
'timestamp',
),
'date' => array(
'date',
),
'time' => array(
'time',
),
);
Mas estou com uma pequena sensação de estar fazendo gambiarra.
A ideia seria registrar estes (ou mais.. ainda estou trabalhando neles) tipos de maneira padronizada para a aplicação. Daí se eu preciso recuperar um valor no PHP, utilizo a função adequada. Se eu quero a constante do PDO, utilizo outra função que converta.
Exemplo: chamo convertToPDOType( 'string' ) e ele retornaria: PDO::PARAM_STR... e assim por diante.
Eu acho que esse é o caminho, mas como disse, estou com uma sensação de poder fazer de um jeito melhor.
Cara, você está caindo no KISS. Você não precisa desse mapeamento.
Aproveite que o PHP é dinamicamente tipado e não amarre a sua implementação.
A única distinção que você precisa fazer é dos tipos numéricos no banco de dados que não precisam de quotados, no demais, são, intrinsecamente strings.
Eu já tentei fazer essa segregação de tipos e a coisa não fluiu muito bem...
De acordo, Henrique... Obrigado pela contribuição, porém eu ainda quero especificar internamente o tipo de dado a ser trabalhado pois pretendo automatizar todo o processo de trabalho com tipos entre o PHP e o banco, no caso mysql (isso vai ser muito útil no futuro, para trabalhar com formulários, datas, etc.).
Enfim, depois de pensar aqui um pouco, eu cheguei à esses dois métodos:
protected function convertDbType( $db_type ) {
if ( !empty( static::$_dataTypes ) )
foreach( static::$_dataTypes as $type_name => $type )
foreach( $type as $db_type_name )
if ( Basics\String::contains( $db_type , $db_type_name ) )
return $type_name;
return 'string';
}
Esse é simples: compara o tipo retornado pelo mysql, que poderia ser por exemplo: int(11) unsigned, e retorna o tipo pré-estabelecido pela aplicação no padrão que eu postei no post anterior. Nesse caso específico, retornaria 'int'.
E para converter o tipo para PDO, fiz utilizando o conceito que você mesmo disse em seu post, resultando nisso aqui:
/**
* Converts pattern type to PDO type. Ex: 'string' => PDO::PARAM_STR
* @param string $type
* @return int
*/
public static function getPDOType( $type ) {
switch( $type ):
case 'int':
return \PDO::PARAM_INT;
default:
return \PDO::PARAM_STR;
endswitch;
}
E o resultado da minha array, 100% satisfatório (pelo menos até agora.. vamos ver os próximos capítulos, hehe..):
Array
(
[artigos] => Array
(
[0] => Array
(
[field] => id
[type] => int
[value] =>
)
[1] => Array
(
[field] => titulo
[type] => string
[value] =>
)
)
[lines] => Array
(
[0] => Array
(
[field] => line_name
[type] => string
[value] =>
)
)
[noticias] => Array
(
[0] => Array
(
[field] => id
[type] => int
[value] =>
)
[1] => Array
(
[field] => title
[type] => string
[value] =>
)
)
)
Agradeço aos que tentaram ajudar. Vou marcar como resolvido, mas se alguém tiver alguma sugestão diferente, sinta-se à vontade.
[]s!
Sim, entendi sua intenção...
Mas não seria muito mais simples apenas utilizar as funções is_*???
A conversão da linguagem para o banco pode ser necessária (por exemplo, ao trabalhar com datas: o MySQL não aceita datas no formato brasileiro), mas a volta não é verdadeira.
Se você tem um campo 'Date', você tem CERTEZA que aquilo é uma data. Como você sabe identificar qual campo é o que pelo nome dele, então pode mandar ver no date_format que tá tudo certo, não precisa de informação de tipo, pq ela está implícita.
>
[ 'tipo' ] => 'aqui eu estou em dúvida do que colocar' ), ...ate onde sei o php ja te retorna eles nos formatos respectivos..
sendo assim..
seria fazer as condições pra monta os BindValue!
foreach($array as $key=> $values)
if(is_int($values[$key]))
$this->binds = PDO::PARAM_INT
ou marca na propria array como você ta fazendo msm
[ 'tipo' ] => 'PDO::PARAM_STR',