回答:
私はあなたのためにcodeigniterバージョンを持っています。また、値から引用符を取り除きます。
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;
}
次のようにクエリして値を取得できます。
SELECT SUBSTRING(COLUMN_TYPE,5)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='databasename'
AND TABLE_NAME='tablename'
AND COLUMN_NAME='columnname'
そこから配列に変換する必要があります:
ENUM列のすべての可能な値を決定する場合は、SHOW COLUMNS FROM tbl_name LIKE enum_colを使用して、出力のType列のENUM定義を解析します。
あなたは次のようなものが欲しいでしょう:
$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]);
これにより、引用符で囲まれた値が得られます。MySQLは常にこれらを単一引用符で囲んで返します。値の単一引用符は、単一引用符でエスケープされます。おそらくtrim($val, "'")、各配列要素を安全に呼び出すことができます。あなた''だけに変換したいと思うでしょう'。
以下は、引用符なしの$ trimmedvals配列項目を返します。
$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
これは上記の多くのようなものですが、ループなしで結果を提供し、あなたが本当に望んでいるようになります:選択オプションを生成するための単純な配列です。
ボーナス:SETおよび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:配列([0] =>赤[1] =>緑[2] =>青)
これは、MySQLのENUMデータ型が悪であるChris Komlenicの8つの理由の1つです。
4.個別のENUMメンバーのリストを取得するのは面倒です。
非常に一般的なニーズは、データベースから可能な値を選択ボックスまたはドロップダウンリストに入力することです。このような:
色を選択:
[ select box ]これらの値が「colors」という名前の参照テーブルに格納されている場合、必要なものは次のとおりです。
SELECT * FROM colorsです。...これを解析して、ドロップダウンリストを動的に生成できます。参照テーブルで色を追加または変更できます。セクシーな注文フォームは自動的に更新されます。驚くばかり。次に、悪質なENUMについて考えてみましょう。メンバーリストをどのように抽出しますか?テーブルのENUM列にDISTINCT値を照会することもできますが、その場合、実際に使用され、テーブルに存在する値のみが返されます。可能なすべての値が返されるとは限りません。INFORMATION_SCHEMAをクエリして、スクリプト言語でクエリ結果から解析することができますが、これは不必要に複雑です。実際、ENUM列のメンバーリストを抽出するエレガントで純粋なSQLの方法は知りません。
文字列は、CSV(カンマ区切り値)文字列であるかのように解析できます。PHPには、CSV文字列を配列に変換するstr_getcsvと呼ばれる優れた組み込み関数があります。
// 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);
これにより、次のような結果が得られます。
Array
(
[0] => blond
[1] => brunette
[2] => redhead
)
この方法では、文字列に単一引用符を含めることもできます(2つの単一引用符の使用に注意してください)。
$enum_or_set = "'blond','brunette','red''head'";
Array
(
[0] => blond
[1] => brunette
[2] => red'head
)
str_getcsv機能の詳細については、PHPマニュアルを確認してください。 http://uk.php.net/manual/en/function.str-getcsv.php
str_getcsvPHP 5> = 5.3.0でのみ機能します。以前のバージョンでこの機能を使用したい場合は、このファイルを含めることができます。
より最新の方法で、これは私にとってうまくいきました:
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;
}
最終的に、「enum()」から分離された列挙値は単なるCSV文字列なので、そのように解析します。
これは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);
これは、Laravelフレームワークに適合したPatrick Savalleによって提供された同じ関数です。
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;
}
$row = db_fetch_object($result);
if($row){
$type = $row->Type;
preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
return $matches[1];
}
これを試して
describe table columnname
そのテーブルのその列に関するすべての情報を提供します。
一部のモデルのメソッドとしてCodeigniter適応バージョン:
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];
}
結果:
array(2) {
[0]=> string(13) "administrator"
[1]=> string(8) "customer"
}
皆さんは奇妙で複雑な正規表現パターンを使用していますx)
これが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()'"));
}
この構文を使用して、MySQL QUERYで列挙可能な値を取得できます。
$syntax = "SELECT COLUMN_TYPY FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = '{$THE_TABLE_NAME}'
AND COLUMN_NAME = '{$THE_COLUMN_OF_TABLE}'";
そして、あなたは値を取得します、例:enum( 'Male'、 'Female')
これは、構文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;
}
?>
Laravelの場合、これはうまくいきました:
$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);
出力:
Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
このスレッドの他のすべての回答の問題は、列挙内の文字列のすべての特殊なケースを適切に解析するものがないことです。
ループのために私を投げていた最大の特別なケース文字は、それらが一緒に2つの単一引用符としてエンコードされているため、単一引用符でした!したがって、たとえば、値を持つ列挙型'a'は次のようにエンコードされますenum('''a''')ます。恐ろしいですよね?
解決策は、MySQLを使用してデータを解析することです!
他の誰もがこのスレッドでPHPを使用しているので、それを使用します。以下は完全なコードです。後で説明します。パラメータ$FullEnumStringは、他のすべての回答から使用したいメソッドから抽出された列挙型文字列全体を保持します。RunQuery()およびFetchRow()(非関連)は、お気に入りのDBアクセス方法の代役です。
function GetDataFromEnum($FullEnumString)
{
if(!preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches))
return null;
return FetchRow(RunQuery('SELECT '.$Matches[1]));
}
preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)enumの値が期待どおりに一致することを確認します"enum(".$STUFF.")"(つまり、前後に何もありません)。preg_matchが失敗した場合、NULLが返されます。
これはpreg_matchまた、奇妙なSQL構文でエスケープされた文字列のリストをに保存し$Matches[1]ます。次に、その中から実際のデータを取得できるようにしたいと考えています。だからあなたはただ走る"SELECT ".$Matches[1]、で、最初のレコードの文字列の完全なリストが得られます。
したがって、そのレコードを FetchRow(RunQuery(...))完了です。
このすべてをSQLで実行したい場合は、以下を使用できます。
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誰かがそれについて何か言うのを防ぐために、いいえ、この方法がSQLインジェクションにつながるとは思いません。
可能な値のリストを取得する方法は十分に文書化されていますが、括弧で値を返す別の答えを拡張して、コンマ区切りのリストを残してそれらを取り除き、いつでも分解型関数を使用できるようにしました配列を取得する必要があります。
SELECT
SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6) AS val
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'articles'
AND
COLUMN_NAME = 'status'
はSUBSTRING現在、6文字目から始まり、合計より6文字短い長さを使用して、末尾の括弧を削除しています。
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);
enumフィールドを使用している場合、割り当てられる値が「先験的」に知られていることを意味するとは誰も考えていないのは異常なことです。
したがって、値が「アプリオリ」であることがわかっている場合、それらを管理する最善の方法は、非常に単純なEnumクラスを使用することです。
ルールにキスし、1つのデータベース呼び出しを保存します。
<?php
class Genre extends \SplEnum {
const male = "Male";
const female = "Female";
}
私はこの方法で列挙値を取得します:
SELECT COLUMN_TYPE
FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = 'tableName'
AND COLUMN_NAME = 'columnName';
このSQLを実行すると、次のようになります。enum( 'BDBL'、 'AB Bank')
次に、次のコードを使用して値だけをフィルタリングしました:
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
var_dump($enum) ;
出力:
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 ;
例:
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'
enum( ''、 'X''XX')では機能しません