ã¯ããã« ããã«ã¡ã¯ããããã£æ ªåŒäŒç€Ÿå
¥äŒã·ã¹ãã ããŒã ã®é«çã§ãã æè¿ãã¹ã¿ããŒã¿ç®¡çã®ããã«ãAdminer Editorãšããã¢ããªã±ãŒã·ã§ã³ã詊ããŠã¿ãŸããã®ã§ç޹ä»ããŸãã èæ¯ ã·ã¹ãã èšå®ããã¹ã¿ããŒã¿ãDBäžã®ããŒãã«ã§ç®¡çããŠããéã«ãæäœãã¹ã«ãã£ãŠã¯åœ±é¿ã倧ããããSQLãçŽæ¥æäœããããããŸããããã®ããã瀟å
éçšããŒã«ãäœæããããšããããŸãããã·ã³ãã«ãªããŒã¿ã§ããã°æ±çšçãªããŒã«ã§ååãªå ŽåããããšæããŸãã æ±çšçãªããŒã«ãšããŠAdminer Editorãšããã¢ããªã±ãŒã·ã§ã³ãæ€èšŒããŸãããæ¬èšäºã§ã¯å®éã«äœ¿ãäžã§å¿
èŠãªæ©èœãšããŠä»¥äžãæããŠã«ã¹ã¿ãã€ãºäŸãšåäœç¢ºèªãããŠããŸãã ããŒã¿æäœä»¥å€ã®ããŒãã«äœæã倿޿äœãããããªã äžèŠãªããŒãã«ã¯èŠããªãããã«ããã äžèŠãªåã¯èŠããªãããã«ããã 誰ãããŒã¿ãæäœãããèšé²ãæ®ããã ã¢ã¯ã»ã¹å¶éãããã Adminer Editorãšã¯ Adminer Editor ãšã¯PHP補ã®DBããŒã¿ç·šéããŒã«ã§ããSQLãæäœããã«ç»é¢äžã®æäœã ãã§ããŒãã«äžã®ããŒã¿ä¿®æ£ãã§ããŸããé¡äŒŒã®ããŒã«ã«AdminerããããŸãããAdminerãšæ¯èŒãããšããŒãã«äœæãåé€ãšãã£ãDDLãå¶éãããŠããããDB管çè
ãšããããã¯DBå©çšè
ã®ããã®ããŒã«ã«ãªããŸãã ãŸããMySQLãPostgreSQLãOracleDBãMicrosoft SQL ServerçããŸããŸãªRDBMSã«å¯Ÿå¿ããŠããŸãã ããŒã«æ¬äœã¯åäžã®PHPãã¡ã€ã«ãšãªã£ãŠããå°å
¥ãããããã¯ã©ã¹ãç¶æ¿ããŠã€ã³ã¹ã¿ã³ã¹ã¡ãœããããªãŒããŒã©ã€ãããããšã§PHPè§Šãããšãã§ããã°ç°¡åã«ã«ã¹ã¿ãã€ãºã§ããŸãã ä»åã¯ãå°å
¥ã®æè»œããšå©çšã§ããRDBMSã®è±å¯ãããæ€èšŒããŠã¿ãŸããã ã㢠ãœãŒã¹ã³ãŒããšå®è¡ç°å¢ã¯DockerãçšæããŠããŸããMySQLãæäŸããŠãã world database ãšãããµã³ãã«ããŒã¿ãMySQLã«ã€ã³ããŒãããŠæäœããŠããŸãã®ã§ãå®éã«è§Šã£ãŠã¿ãããšããæ¹ã¯READMEãåèã«æ§ç¯ããŠã¿ãŠãã ããã https://github.com/octop162/adminer-editor-customized Adminer Editorã®èšå®ãšã«ã¹ã¿ãã€ãºæ¹æ³ å°å
¥ã«å¿
èŠãªã®ã¯Adminer Editoræ¬äœãšèšå®ãã¡ã€ã«ã®2ã€ã ãã§ããèšå®ãã¡ã€ã«ã«ã¯DBã®ãã¹ãåããŠãŒã¶ãŒåããã¹ã¯ãŒãçã®åºæ¬èšå®ã®ä»ãããŒã¿æ¿å
¥ã倿Žãåé€çã®æäœãããéã«åŒã°ããã¡ãœããã®ãªãŒããŒã©ã€ããããŸãã ããã§ã¯èšå®ãã¡ã€ã«ãworld.phpãæ¬äœãeditor.phpãšããŠããŸããworld.phpã«ã¢ã¯ã»ã¹ãããšAdminer Editorãå©çšã§ããŸããããã«adminer.cssãèšçœ®ããããšã§CSSãèªã¿èŸŒã¿åæ ããŠãããŸãã èšå®æ¹æ³ã¯ä»¥äžããŒãžãåèã«ããŠããŸãã https://www.adminer.org/en/extension/ . âââ adminer.css âââ editor.php âââ world.php ããããã®æ©èœå®çŸæ¹æ³ åè¿°ããã«ã¹ã¿ã æ¹æ³ã«ããæ©èœè¿œå ããŠããŸãã äžèŠãªããŒãã«ãé衚瀺ã«ããã tableNameããªãŒããŒã©ã€ãããããšã§ã©ã®ããŒãã«ã衚瀺ããããå¶åŸ¡ã§ããŸããé衚瀺ã«ãããããŒãã«åãªã空æåãè¿ããŸãã ããã§ã¯ããŒãã«åã country  ãé衚瀺ã«ããŠããŸãã function tableName($tableStatus) { // countryããŒãã«ãé衚瀺 $ignored_list = ['country']; if (in_array($tableStatus["Name"], $ignored_list, true)) { return ''; } return parent::tableName($tableStatus); } äžèŠãªããŒãã«ã®åãé衚瀺ã«ããã åæ§ã«é衚瀺ã«ãããååã¯ç©ºæåãè¿ããšé衚瀺ã«ã§ããŸããããã§ã¯ã ID åãé衚瀺ã«ããŠããŸãã function fieldName($field, $order = 0) { // IDåãé衚瀺 $ignored_list = ['ID']; if (in_array($field["field"], $ignored_list, true)) { return ''; } return parent::fieldName($field, $order = 0); } æäœèšé²ãæ®ã å¿
èŠãªãã¡ã€ã«ãå¢ããŠããŸããŸãããå©äŸ¿æ§ãèããŠPHPã®ãã°ã©ã€ãã©ãªã§ããMonologãå°å
¥ããŸããè¿œå æ
å ±ãšããŠIPã¢ãã¬ã¹ãX-Forwarded-Forããã°ã€ã³ãŠãŒã¶ãŒãåºåããããšã§èª°ãæäœããããããããã«ããŠããŸãã class AdminerSoftware extends Adminer { private $logger; function __construct() { $this->logger = $this->getLogger('php://stdout', Level::Debug); } function getLogger($filename, $level = Level::Debug) { $logger = new Logger('adminer'); $handler = new StreamHandler($filename, $level); $handler->setFormatter(new JsonFormatter()); $logger->pushHandler($handler); $logger->pushProcessor(function ($record) { $record['extra']['remote_user'] = $_SERVER['REMOTE_USER']; $record['extra']['remote_ip'] = $_SERVER['REMOTE_ADDR']; $record['extra']['xff'] = $_SERVER['X-Forwarded-For']; return $record; }); return $logger; } ... SELECTãINSERTã UPDATEãDELETEã¯ãããã selectQuery ã messageQuery ã¡ãœãããAdminer Editoræ¬äœããåŒã°ãããããçšæãããã¬ãŒãªããžã§ã¯ãã§ãã°åºåããŸãã function selectQuery($query, $time, $failed = false) { $output_query = str_replace("\\n", " ", $query); $this->logger->debug($output_query); } function messageQuery($query, $time, $failed = false) { $output_query = str_replace("\\n", " ", $query); $this->logger->info($output_query); } Monologå°å
¥åŸã¯ä»¥äžã®ãããªãã¡ã€ã«æ§æã«ãªããŸããã . |-- composer.json |-- composer.lock |-- public | |-- adminer.css | |-- editor.php | `-- world.php `-- vendor |-- autoload.php |-- composer |-- monolog `-- psr ã¢ã«ãŠã³ãèªèšŒãã ãã°ã€ã³èªèšŒã¯ login ã¡ãœãããæ
åœããŠããŸãããŠãŒã¶åããã¹ã¯ãŒããå
¥åãããšåŒæ°ãšããŠæž¡ãããŸãã®ã§ãç°¡æçã«èªèšŒãããã®ã§ããã°ãããããæ¯èŒããã ãã§èªèšŒã§ããŸãã å®éã«ã¯IPã¢ãã¬ã¹å¶éããªããŒã¹ãããã·å°å
¥ããããã¹ã¯ãŒããããã·ã¥åããŠããç察çãå¿
èŠã«æããŸãã 以äžã¯IPã¢ãã¬ã¹ãããšã«ããŠã¢ã¯ã»ã¹å¶éããããäŸãšãç°¡æçãªèªèšŒã®äŸã§ãã <?php $permit_ip = ["x.x.x.x", "y.y.y.y"]; if (!in_array($_SERVER['REMOTE_ADDR'], $permit_ip, true)) { } ... class AdminerSoftware extends Adminer { ... function login($login, $password) { return $login === 'xxxx' && $password === 'yyyy'; } å®éã«è§Šã£ãŠã¿ã äžèšã®èšå®åŸãããŒã«ã«ç°å¢ã§åäœç¢ºèªã宿œããŸãã â ãã°ã€ã³ç»é¢  â¡ããŒãã«äžèЧïŒcountryãé衚瀺ã«ãªã£ãŠããŸãïŒã â¢ããŒã¿äžèЧã§ç¥å¥å·çã§æ€çŽ¢ããŠã¿ãŸãïŒIDåãé衚瀺ã«ãªã£ãŠããŸãïŒã  â£ç¥å¥å·çã«äººå£2000人ã®çºTestCityã远å ããŠã¿ãŸããè¿œå æãIDåã¯è¡šç€ºãããŠããŸããã â€ç¡äºTestCityã远å ãããŸããã â¥ç·šéãªã³ã¯ãæŒããšä¿®æ£ãåé€ãã§ããŸãã âŠãã°ããããããã®æäœã確èªã§ããŸããã adminer-editor-customized-adminer-1 | {"message":"INSERT INTO `city` (`Name`, `CountryCode`, `District`, `Population`) VALUES ('TestCity', 'JPN', 'Kanagawa', '2000');","context":{},"level":200,"level_name":"INFO","channel":"adminer","datetime":"2023-06-16T01:46:58.380121+00:00","extra":{"remote_user":null,"remote_ip":"xxxx","xff":null}} adminer-editor-customized-adminer-1 | {"message":"UPDATE `city` SET `Name` = 'TestCity', `CountryCode` = 'JPN', `District` = 'Kanagawa', `Population` = '3000' WHERE `ID` = '4081';","context":{},"level":200,"level_name":"INFO","channel":"adminer","datetime":"2023-06-16T01:48:36.217265+00:00","extra":{"remote_user":null,"remote_ip":"xxxx","xff":null}} adminer-editor-customized-adminer-1 | {"message":"DELETE FROM `city` WHERE `ID` = '4081';","context":{},"level":200,"level_name":"INFO","channel":"adminer","datetime":"2023-06-16T01:50:09.335932+00:00","extra":{"remote_user":null,"remote_ip":"xxxx","xff":null}} ãããã« æ¬èšäºã§ã¯ãAdminer Editorãã«ã¹ã¿ãã€ãºããããšã§éçšäžå¿
èŠãªæ©èœã远å ã§ããããšãæ€èšŒããŸãããåèã«ãªãã°å¹žãã§ãã We are hiring! ãããã£ã§ã¯ãããŸããŸãªãããã¯ããžææŠãããšã³ãžãã¢ãçµ¶è³åéäžã§ãïŒ ãèå³ã®ããæ¹ã¯ä»¥äžã®æ¡çšãµã€ããããæ°è»œã«ãé£çµ¡ãã ããïŒ ãããã£æ ªåŒäŒç€Ÿæ¡çšæ
å ± Tech TalkãMeetUpãéå¬ããŠãããŸãïŒ ãã¡ãããæ°è»œã«ãå¿åãã ããïŒ Event â NIFTY engineering