Réponses:
J'ai une version de codeigniter pour vous. Il supprime également les guillemets des valeurs.
function get_enum_values( $table, $field )
{
$type = $this->db->query( "SHOW COLUMNS FROM {$table} WHERE Field = '{$field}'" )->row( 0 )->Type;
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
return $enum;
}
Vous pouvez obtenir les valeurs en l'interrogeant comme ceci:
SELECT SUBSTRING(COLUMN_TYPE,5)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='databasename'
AND TABLE_NAME='tablename'
AND COLUMN_NAME='columnname'
À partir de là, vous devrez le convertir en un tableau:
Si vous souhaitez déterminer toutes les valeurs possibles pour une colonne ENUM, utilisez SHOW COLUMNS FROM tbl_name LIKE enum_col et analysez la définition ENUM dans la colonne Type de la sortie.
Vous voudriez quelque chose comme:
$sql = "SHOW COLUMNS FROM `table` LIKE 'column'";
$result = $db->query($sql);
$row = $result->fetchRow();
$type = $row['Type'];
preg_match('/enum\((.*)\)$/', $type, $matches);
$vals = explode(',', $matches[1]);
Cela vous donnera les valeurs citées. MySQL les renvoie toujours entre guillemets simples. Un guillemet simple dans la valeur est échappé par un guillemet simple. Vous pouvez probablement appeler en toute sécurité trim($val, "'")chacun des éléments du tableau. Vous voudrez convertir ''en juste '.
Ce qui suit renverra les éléments du tableau $ trimmedvals sans guillemets:
$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
C'est comme beaucoup de ce qui précède, mais vous donne le résultat sans boucles, ET vous donne ce que vous voulez vraiment: un simple tableau pour générer des options de sélection.
BONUS: Cela fonctionne pour les types de champs SET ainsi que ENUM.
$result = $db->query("SHOW COLUMNS FROM table LIKE 'column'");
if ($result) {
$option_array = explode("','",preg_replace("/(enum|set)\('(.+?)'\)/","\\2", $result[0]->Type));
}
$ option_array: Array ([0] => rouge [1] => vert [2] => bleu)
C'est l'une des 8 raisons de Chris Komlenic pour lesquelles le type de données ENUM de MySQL est mauvais :
4. Obtenir une liste des membres ENUM distincts est une tâche difficile.
Un besoin très courant est de remplir une boîte de sélection ou une liste déroulante avec les valeurs possibles de la base de données. Comme ça:
Choisissez la couleur:
[ select box ]Si ces valeurs sont stockées dans une table de référence nommée «couleurs», tout ce dont vous avez besoin est:
SELECT * FROM colors... qui peut ensuite être analysée pour générer dynamiquement la liste déroulante. Vous pouvez ajouter ou modifier les couleurs dans le tableau de référence, et vos bons de commande sexy seront automatiquement mis à jour. Impressionnant.Considérons maintenant le mal ENUM: comment extraire la liste des membres? Vous pouvez interroger la colonne ENUM de votre table pour les valeurs DISTINCT, mais cela ne renverra que les valeurs qui sont réellement utilisées et présentes dans la table , pas nécessairement toutes les valeurs possibles. Vous pouvez interroger INFORMATION_SCHEMA et les analyser à partir du résultat de la requête avec un langage de script, mais c'est inutilement compliqué. En fait, je ne connais aucun moyen élégant et purement SQL d'extraire la liste des membres d'une colonne ENUM.
Vous pouvez analyser la chaîne comme s'il s'agissait d'une chaîne CSV (Comma Separated Value). PHP a une excellente fonction intégrée appelée str_getcsv qui convertit une chaîne CSV en un tableau.
// This is an example to test with
$enum_or_set = "'blond','brunette','redhead'";
// Here is the parser
$options = str_getcsv($enum_or_set, ',', "'");
// Output the value
print_r($options);
Cela devrait vous donner quelque chose de similaire à ce qui suit:
Array
(
[0] => blond
[1] => brunette
[2] => redhead
)
Cette méthode vous permet également d'avoir des guillemets simples dans vos chaînes (notez l'utilisation de deux guillemets simples):
$enum_or_set = "'blond','brunette','red''head'";
Array
(
[0] => blond
[1] => brunette
[2] => red'head
)
Pour plus d'informations sur la fonction str_getcsv, consultez le manuel PHP: http://uk.php.net/manual/en/function.str-getcsv.php
str_getcsvne fonctionne qu'en PHP 5> = 5.3.0, vous pouvez inclure ce fichier si vous souhaitez obtenir cette fonctionnalité dans les versions antérieures.
Une façon plus à jour de le faire, cela a fonctionné pour moi:
function enum_to_array($table, $field) {
$query = "SHOW FIELDS FROM `{$table}` LIKE '{$field}'";
$result = $db->query($sql);
$row = $result->fetchRow();
preg_match('#^enum\((.*?)\)$#ism', $row['Type'], $matches);
$enum = str_getcsv($matches[1], ",", "'");
return $enum;
}
En fin de compte, les valeurs d'énumération lorsqu'elles sont séparées de "enum ()" ne sont qu'une chaîne CSV, alors analysez-les comme telles!
voici pour mysqli
function get_enum_values($mysqli, $table, $field )
{
$type = $mysqli->query("SHOW COLUMNS FROM {$table} WHERE Field = '{$field}'")->fetch_array(MYSQLI_ASSOC)['Type'];
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
return $enum;
}
$deltypevals = get_enum_values($mysqli, 'orders', 'deltype');
var_dump ($deltypevals);
Voici la même fonction donnée par Patrick Savalle adaptée pour le framework Laravel
function get_enum_values($table, $field)
{
$test=DB::select(DB::raw("show columns from {$table} where field = '{$field}'"));
preg_match('/^enum\((.*)\)$/', $test[0]->Type, $matches);
foreach( explode(',', $matches[1]) as $value )
{
$enum[] = trim( $value, "'" );
}
return $enum;
}
Je veux simplement ajouter à ce que dit jasonbar , lors d'une requête comme:
SHOW columns FROM table
Si vous obtenez le résultat sous forme de tableau, il ressemblera à ceci:
array([0],[Field],[1],[Type],[2],[Null],[3],[Key],[4],[Default],[5],[Extra])
Où [n] et [texte] donnent la même valeur.
Pas vraiment dit dans aucune documentation que j'ai trouvée. Tout simplement bon de savoir ce qu'il y a d'autre.
$row = db_fetch_object($result);
if($row){
$type = $row->Type;
preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
return $matches[1];
}
essaye ça
describe table columnname
vous donne toutes les informations sur cette colonne dans ce tableau;
Codeigniter adaptant la version comme méthode de certains modèles:
public function enum_values($table_name, $field_name)
{
$query = $this->db->query("SHOW COLUMNS FROM `{$table_name}` LIKE '{$field_name}'");
if(!$query->num_rows()) return array();
preg_match_all('~\'([^\']*)\'~', $query->row('Type'), $matches);
return $matches[1];
}
Résultat:
array(2) {
[0]=> string(13) "administrator"
[1]=> string(8) "customer"
}
Vous utilisez tous des modèles de regex étranges et complexes x)
Voici ma solution sans preg_match:
function getEnumTypes($table, $field) {
$query = $this->db->prepare("SHOW COLUMNS FROM $table WHERE Field = ?");
try {$query->execute(array($field));} catch (Exception $e) {error_log($e->getMessage());}
$types = $query->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE, 1)[$field];
return explode("','", trim($types, "enum()'"));
}
Vous pouvez utiliser cette syntaxe pour obtenir une énumération des valeurs possibles dans MySQL QUERY:
$syntax = "SELECT COLUMN_TYPY FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = '{$THE_TABLE_NAME}'
AND COLUMN_NAME = '{$THE_COLUMN_OF_TABLE}'";
et vous obtenez une valeur, exemple: enum ('Male', 'Female')
voici un exemple de sytaxe php:
<?php
function ($table,$colm){
// mysql query.
$syntax = mysql_query("SELECT COLUMN_TYPY FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = '$table' AND COLUMN_NAME ='$colm'");
if (!mysql_error()){
//Get a array possible values from table and colm.
$array_string = mysql_fetch_array($syntax);
//Remove part string
$string = str_replace("'", "", $array_string['COLUMN_TYPE']);
$string = str_replace(')', "", $string);
$string = explode(",",substr(5,$string));
}else{
$string = "error mysql :".mysql_error();
}
// Values is (Examples) Male,Female,Other
return $string;
}
?>
Pour Laravel, cela a fonctionné:
$result = DB::select("SHOW COLUMNS FROM `table_name` LIKE 'status';");
$regex = "/'(.*?)'/";
preg_match_all( $regex , $result[0]->Type, $enum_array );
$enum_fields = $enum_array[1];
echo "<pre>";
print_r($enum_fields);
Production:
Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
Le problème avec toutes les autres réponses dans ce thread est qu'aucune d'entre elles n'analyse correctement tous les cas spéciaux des chaînes dans l'énumération.
Le plus grand caractère de cas spécial qui me jetait pour une boucle était les guillemets simples, car ils sont eux-mêmes encodés sous forme de 2 guillemets simples ensemble! Ainsi, par exemple, une énumération avec la valeur 'a'est codée commeenum('''a''') . Horrible, non?
Eh bien, la solution est d'utiliser MySQL pour analyser les données à votre place!
Puisque tout le monde utilise PHP dans ce fil, c'est ce que je vais utiliser. Voici le code complet. Je vais l'expliquer après. Le paramètre $FullEnumStringcontiendra toute la chaîne d'énumération, extraite de la méthode que vous souhaitez utiliser de toutes les autres réponses. RunQuery()et FetchRow()(non associatif) sont des substituts pour vos méthodes d'accès DB préférées.
function GetDataFromEnum($FullEnumString)
{
if(!preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches))
return null;
return FetchRow(RunQuery('SELECT '.$Matches[1]));
}
preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)confirme que la valeur enum correspond à ce que nous attendons, c'est-à-dire "enum(".$STUFF.")"(sans rien avant ou après). Si le preg_match échoue, NULLest renvoyé.
Cela preg_matchstocke également la liste des chaînes, échappées dans une syntaxe SQL étrange, dans $Matches[1]. Ensuite, nous voulons pouvoir en tirer les vraies données. Alors vous venez de courir "SELECT ".$Matches[1], et vous avez une liste complète des chaînes de votre premier enregistrement!
Alors sortez simplement cet enregistrement avec un FetchRow(RunQuery(...))et vous avez terminé.
Si vous vouliez faire tout cela en SQL, vous pouvez utiliser ce qui suit
SET @TableName='your_table_name', @ColName='your_col_name';
SET @Q=(SELECT CONCAT('SELECT ', (SELECT SUBSTR(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE)-6) FROM information_schema.COLUMNS WHERE TABLE_NAME=@TableName AND COLUMN_NAME=@ColName)));
PREPARE stmt FROM @Q;
EXECUTE stmt;
PS Pour empêcher quiconque de dire quelque chose à ce sujet, non, je ne crois pas que cette méthode puisse conduire à une injection SQL.
Pour récupérer la liste des valeurs possibles a été bien documentée, mais en développant une autre réponse qui renvoyait les valeurs entre parenthèses , je voulais les supprimer en me laissant avec une liste séparée par des virgules qui me permettrait ensuite d'utiliser une fonction de type éclaté chaque fois que je nécessaire pour obtenir un tableau.
SELECT
SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6) AS val
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'articles'
AND
COLUMN_NAME = 'status'
Le SUBSTRINGcommence maintenant au 6ème caractère et utilise une longueur qui est de 6 caractères plus courte que le total, en supprimant la parenthèse de fin.
Pour PHP 5.6+
$mysqli = new mysqli("example.com","username","password","database");
$result = $mysqli->query("SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='table_name' AND COLUMN_NAME='column_name'");
$row = $result->fetch_assoc();
var_dump($row);
Il est extraordinaire qu'aucun de vous n'ait pensé que si vous utilisez un champ enum, cela signifie que les valeurs à attribuer sont connues "a priori".
Par conséquent, si les valeurs sont connues "a priori", la meilleure façon de les gérer est d'utiliser une classe Enum très simple.
Baiser la règle et enregistrer un appel de base de données.
<?php
class Genre extends \SplEnum {
const male = "Male";
const female = "Female";
}
J'obtiens les valeurs d'énumération de cette manière:
SELECT COLUMN_TYPE
FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = 'tableName'
AND COLUMN_NAME = 'columnName';
En exécutant ce sql, j'ai get: enum ('BDBL', 'AB Bank')
alors j'ai filtré juste la valeur en utilisant le code suivant:
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
var_dump($enum) ;
Production :
array (2) {[0] => string (4) "BDBL" [1] => string (7) "AB Bank"}
DELIMITER //
DROP FUNCTION IF EXISTS ENUM_VALUES;
CREATE FUNCTION ENUM_VALUES(
_table_name VARCHAR(64),
_col_name VARCHAR(64)
) RETURNS JSON
BEGIN
RETURN (
SELECT CAST(CONCAT('[', REPLACE(SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6), "'", '"'), ']') AS JSON)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'db_name'
AND TABLE_NAME = _table_name
AND COLUMN_NAME = _col_name
AND DATA_TYPE = 'enum'
);
END //
DELIMITER ;
Exemple:
SELECT ENUM_VALUES('table_name', 'col_name');
SELECT SUBSTRING (COLUMN_TYPE, 6, LENGTH (COLUMN_TYPE) - 6) AS val FROM information_schema.COLUMNS WHERE TABLE_NAME = 'articles' AND COLUMN_NAME = 'status'
Ne fonctionnerait pas pour enum ('', 'X''XX')