Risposte:
Ho una versione di codeigniter per te. Inoltre rimuove le virgolette dai valori.
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;
}
Puoi ottenere i valori eseguendo una query in questo modo:
SELECT SUBSTRING(COLUMN_TYPE,5)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='databasename'
AND TABLE_NAME='tablename'
AND COLUMN_NAME='columnname'
Da lì dovrai convertirlo in un array:
Se si desidera determinare tutti i valori possibili per una colonna ENUM, utilizzare SHOW COLUMNS FROM tbl_name LIKE enum_col e analizzare la definizione ENUM nella colonna Type dell'output.
Vorresti qualcosa come:
$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]);
Questo ti darà i valori citati. MySQL li restituisce sempre racchiusi tra virgolette singole. Una singola virgoletta nel valore è preceduta da una singola virgoletta. Probabilmente puoi chiamare in modo sicuro trim($val, "'")ciascuno degli elementi dell'array. Ti consigliamo di convertire ''in just '.
Quanto segue restituirà gli elementi dell'array $ trimmedvals senza virgolette:
$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
Questo è come molti dei precedenti, ma ti dà il risultato senza loop, E ti fa ottenere quello che vuoi veramente: un semplice array per generare opzioni di selezione.
BONUS: funziona sia per i tipi di campo SET che per quelli 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] => rosso [1] => verde [2] => blu)
Questo è uno degli 8 motivi per cui il tipo di dati ENUM di MySQL è malvagio di Chris Komlenic :
4. Ottenere un elenco di membri ENUM distinti è un problema.
Una necessità molto comune è quella di popolare una casella di selezione o un elenco a discesa con i possibili valori dal database. Come questo:
Scegli il colore:
[ select box ]Se questi valori sono memorizzati in una tabella di riferimento denominata "colors", tutto ciò di cui hai bisogno è:
SELECT * FROM colors... che può quindi essere analizzato per generare dinamicamente l'elenco a discesa. Puoi aggiungere o modificare i colori nella tabella di riferimento e i tuoi moduli d'ordine sexy verranno automaticamente aggiornati. Eccezionale.Ora considera il malvagio ENUM: come estrai l'elenco dei membri? È possibile interrogare la colonna ENUM nella tabella per i valori DISTINCT, ma ciò restituirà solo i valori effettivamente utilizzati e presenti nella tabella , non necessariamente tutti i valori possibili. Puoi eseguire una query su INFORMATION_SCHEMA e analizzarli dal risultato della query con un linguaggio di scripting, ma ciò è inutilmente complicato. In effetti, non conosco alcun modo elegante, puramente SQL per estrarre l'elenco dei membri di una colonna ENUM.
È possibile analizzare la stringa come se fosse una stringa CSV (Comma Separated Value). PHP ha una grande funzione incorporata chiamata str_getcsv che converte una stringa CSV in un array.
// 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);
Questo dovrebbe darti qualcosa di simile al seguente:
Array
(
[0] => blond
[1] => brunette
[2] => redhead
)
Questo metodo consente anche di avere virgolette singole nelle stringhe (notare l'uso di due virgolette singole):
$enum_or_set = "'blond','brunette','red''head'";
Array
(
[0] => blond
[1] => brunette
[2] => red'head
)
Per ulteriori informazioni sulla funzione str_getcsv, consultare il manuale PHP: http://uk.php.net/manual/en/function.str-getcsv.php
str_getcsvfunziona solo in PHP 5> = 5.3.0, puoi includere questo file se desideri ottenere questa funzionalità nelle versioni precedenti.
Un modo più aggiornato per farlo, questo ha funzionato per me:
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;
}
In definitiva, i valori enum quando separati da "enum ()" sono solo una stringa CSV, quindi analizzala come tale!
qui è per 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);
Ecco la stessa funzione data da Patrick Savalle adattata per il 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;
}
Voglio semplicemente aggiungere a ciò che dice jasonbar , quando si interroga come:
SHOW columns FROM table
Se ottieni il risultato come un array, apparirà così:
array([0],[Field],[1],[Type],[2],[Null],[3],[Key],[4],[Default],[5],[Extra])
Dove [n] e [testo] danno lo stesso valore.
Non raccontato in alcun documento che ho trovato. Semplicemente bello sapere cos'altro c'è.
$row = db_fetch_object($result);
if($row){
$type = $row->Type;
preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
return $matches[1];
}
prova questo
describe table columnname
ti dà tutte le informazioni su quella colonna in quella tabella;
Codeigniter adattando la versione come metodo di alcuni modelli:
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];
}
Risultato:
array(2) {
[0]=> string(13) "administrator"
[1]=> string(8) "customer"
}
Tutti voi usate alcuni schemi regex strani e complessi x)
Ecco la mia soluzione senza 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()'"));
}
È possibile utilizzare questa sintassi per ottenere enum possibili valori in MySQL QUERY:
$syntax = "SELECT COLUMN_TYPY FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = '{$THE_TABLE_NAME}'
AND COLUMN_NAME = '{$THE_COLUMN_OF_TABLE}'";
e ottieni valore, esempio: enum ('Male', 'Female')
questo è un esempio di sytax 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;
}
?>
Per Laravel questo ha funzionato:
$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);
Produzione:
Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
Il problema con ogni altra risposta in questo thread è che nessuna di esse analizza correttamente tutti i casi speciali delle stringhe all'interno dell'enum.
Il più grande carattere speciale che mi ha lanciato per un ciclo era virgolette singole, poiché sono codificate come 2 virgolette singole insieme! Quindi, ad esempio, un'enumerazione con il valore 'a'è codificata come enum('''a'''). Orribile, vero?
Bene, la soluzione è usare MySQL per analizzare i dati per te!
Dato che tutti gli altri usano PHP in questo thread, è quello che userò. Di seguito è riportato il codice completo. Lo spiegherò dopo. Il parametro $FullEnumStringconterrà l'intera stringa enum, estratta da qualsiasi metodo tu voglia usare da tutte le altre risposte. RunQuery()e FetchRow()(non associativo) sono sostituti dei tuoi metodi di accesso al database preferiti.
function GetDataFromEnum($FullEnumString)
{
if(!preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches))
return null;
return FetchRow(RunQuery('SELECT '.$Matches[1]));
}
preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)conferma che il valore enum corrisponde a quello che ci aspettiamo, vale a dire, "enum(".$STUFF.")"(senza niente prima o dopo). Se preg_match fallisce, NULLviene restituito.
Questo preg_matchmemorizza anche l'elenco delle stringhe, con escape in una strana sintassi SQL, in $Matches[1]. Quindi, in seguito, vogliamo essere in grado di ottenere i dati reali da quello. Quindi corri "SELECT ".$Matches[1]e hai un elenco completo delle corde nel tuo primo record!
Quindi tira fuori quel disco con un FetchRow(RunQuery(...))e il gioco è fatto.
Se si desidera eseguire l'intera operazione in SQL, è possibile utilizzare quanto segue
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 Per impedire a qualcuno di dire qualcosa al riguardo, no, non credo che questo metodo possa portare a SQL injection.
Per recuperare l'elenco dei possibili valori è stato ben documentato, ma espandendo un'altra risposta che restituiva i valori tra parentesi , volevo eliminarli lasciandomi con un elenco separato da virgole che mi avrebbe quindi permesso di utilizzare una funzione di tipo esplosione ogni volta che lo necessario per ottenere un array.
SELECT
SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6) AS val
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'articles'
AND
COLUMN_NAME = 'status'
L' SUBSTRINGora inizia a carattere 6a e utilizza una lunghezza che è di 6 caratteri più corto del totale, togliendo la parentesi finale.
Per 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);
È straordinario come nessuno di voi abbia pensato che se si utilizza un campo enum significa che i valori da assegnare sono noti "a priori".
Quindi se i valori sono noti "a priori" il modo migliore per gestirli è attraverso una semplicissima classe Enum.
Bacia la regola e salva una chiamata al database.
<?php
class Genre extends \SplEnum {
const male = "Male";
const female = "Female";
}
Ottengo i valori enum in questo modo:
SELECT COLUMN_TYPE
FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = 'tableName'
AND COLUMN_NAME = 'columnName';
Eseguendo questo sql ho ottenuto: enum ('BDBL', 'AB Bank')
quindi ho filtrato solo il valore utilizzando il seguente codice:
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
var_dump($enum) ;
Produzione :
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 ;
Esempio:
SELECT ENUM_VALUES('table_name', 'col_name');
SELEZIONA SUBSTRING (COLUMN_TYPE, 6, LENGTH (COLUMN_TYPE) - 6) AS val FROM information_schema.COLUMNS WHERE TABLE_NAME = 'articles' AND COLUMN_NAME = 'status'
Non funzionerebbe per enum ('', 'X''XX')