Прехвърляне на масиви от файлове към база данни

Ticketa

Registered
Привет,
Разполагам с 17 файла, всеки от които е данни в масив

bg
return [
'key' => 'translate',
'key2' => 'translate2',
'key3' => 'translate3',
];

en
return [
'key' => 'translate',
'key2' => 'translate2',
'key3' => 'translate3',
];


...

Искам ключовете и преводите да ги прехвърля в база данни. За целта съм създал таблица с полета:
id, short_code(взима се от името на файла), key, data


Съответно името на файла отива в колона short_code, key е ключа, data е превода



Как мога да ги прехвърля на веднъж всичките файлове, като започна от en.php ?

1 скрипт , който да попълни самостоятелно всичко?

Обмислям нещо подобно:

$columns = implode(", ",array_keys($insData));
$escaped_values = array_map('mysql_real_escape_string', array_values($insData));
$values = implode(", ", $escaped_values);
$sql = "INSERT INTO `data`($columns) VALUES ($values)";
 
Стигнах до тук:
Проблема е, че по-този начин трябва да имам предварително КЛЮЧ
(например) $array = array("name"=>"pineapple", "color"=>"purple");
По-този начин трябва да имаш КОЛОНА `name` и колона `color`

А примен е по-различна структурата и трябва да се попълват колоните:
pld_id lang_id pld_key pld_data pld_added pld_update

В случая: `lang_id` - езика short_code (файла)
pld_key - ключ
pld_data - съдържанието/превода


Като дебъгна $query
получавам:
insert into promo_lang_data (lang_id, pld_key, pld_data) values (1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);

А би трябвало да има нов ред, нов ред.... и т.н.

Код:
$table_name = "promo_lang_data"; 
insert_data($mysqli, $array, $table_name);



function insert_data($mysqli, $array, $table_name) 
{
   $placeholders = array_fill(0, count($array), '?');

   $keys   = array(); 
   $values = array();
   foreach($array as $k => $v) {
      $keys[] = $k;
      $values[] = !empty($v) ? $v : null;
   }
   $query = "insert into $table_name ".
            '(lang_id, pld_key, pld_data) values '.
            '(1, '.implode(', ', $placeholders).'); '; 
   $stmt = $mysqli->prepare($query);

   $params = array(); 
   foreach ($array as &$value) { 
      $params[] = &$value;
   }
   $types  = array(str_repeat('s', count($params))); 
   $values = array_merge($types, $params); 

   call_user_func_array(array($stmt, 'bind_param'), $values); 

   $success = $stmt->execute();

   if ($success) { 
        print "it worked..."; 
   } else { 
        print "it did not work...";
    }
}
 
Пробвах и така:

Обаче създавам само 1 заявка за insert и се изчезва тази част: insert into $table_name ". '(lang_id, pld_key, pld_data) values при дебъг.

Явно съм на прав път вече.

Код:
$include = array();
$i=0;
foreach ($array as $key => $value) {
  //foreach ($value as $finalVal) {
  /*
    $query = "insert into $table_name ". '(lang_id, pld_key, pld_data) values (1, '.$key.', '.$value.');'; 
    echo $query;
    die;*/
    $include[] = "('$key','$value')";
    $i++;
  //} 
}
$values = implode(",", $include);
$query = "insert into $table_name ". '(lang_id, pld_key, pld_data) values '. '(1, '.implode(",", $include).'); '; 
echo $query;
die;
$stmt = $mysqli->prepare($query);
 
До тук го докарах правилно да създава заявката ред по ред, ключ по клю

Код:
$include = array();
$i=0;
foreach ($array as $key => $value) {
    $include[] = "insert into $table_name ". "(lang_id, pld_key, pld_data) values ". "(1, '$key', '$value');";
    $i++;
}
$values = implode("", $include);
if ($mysqli->query($values) === TRUE) {
  echo "New record created successfully";
} else {
  echo "Error: " . $values . "<br>" . $mysqli->error;
}

Обаче, ми дава грешка при опит да изпълня командата $mysqli->query($values) , връща ми грешка:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insert into promo_lang_data (lang_id, pld_key, pld_data) values (1, 'As seen on.' at line 1


....
ЕДИТ:
.....
Интересно. Коригирах го така;
Код:
$include = array();
foreach ($array as $key => $value) {
    /*
    $include[] = 'insert into '.$table_name.' (lang_id, pld_key, pld_data, pld_added) values ("1", "'.$key.'", "'.$value.'", DATE(NOW()));';
    */
    $sql_I = 'insert into '.$table_name.' (lang_id, pld_key, pld_data, pld_added) values ("1", "'.$key.'", "'.$value.'", DATE(NOW()));';
    if ($mysqli->query($sql_I) === TRUE) {
      echo "New record created successfully";
    } else {
      echo "Error: " . $sql_I . "<br>" . $mysqli->error;
    }
}

Обаче, не добавя всичките заявки. Дава на моменти грешки.

Примерни заявки , които не се добавят:
Визуализирана заявка с грешка:

insert into promo_lang_data (lang_id, pld_key, pld_data, pld_added) values ("1", "Using an XML map, your site will be indexed faster by search engines. Learn more about using a Sitemap ", "Използвайки XML карта, сайтът Ви ще бъде индексиран по-бързо от търсачките. Научете повече за използването Sitemap", DATE(NOW()));

Реална заявка:
insert into promo_lang_data (lang_id, pld_key, pld_data, pld_added) values ("1", "Using an XML map, your site will be indexed faster by search engines. <a href="https://support.google.com/news/publisher-center/answer/9606709?ref_topic=9606468" target="_blank"> Learn more about using a Sitemap </a>", "Използвайки XML карта, сайтът Ви ще бъде индексиран по-бързо от търсачките. <a href="https://support.google.com/news/publisher-center/answer/9606709?ref_topic=9606468" target="_blank">Научете повече за използването Sitemap</a>", DATE(NOW()));


Реално проблема идва от там, че при изпълнение на заявката в самия текст има двойна " или единична ' кавичка и създава проблема.
 
Казуса е решен до изпълнение на заявките:
Код:
$include = array();
foreach ($array as $key => $value) {
    /*
    $include[] = 'insert into '.$table_name.' (lang_id, pld_key, pld_data, pld_added) values ("1", "'.$key.'", "'.$value.'", DATE(NOW()));';
    */
    $sql_I = "insert into $table_name (lang_id, pld_key, pld_data, pld_added) values ('1', '".mysqli_real_escape_string($mysqli, $key)."', '".mysqli_real_escape_string ($mysqli, $value)."', DATE(NOW()));";
    if ($mysqli->query($sql_I) === TRUE) {
      echo "New record created successfully";
    } else {
      echo "Error: " . $sql_I . "<br>" . $mysqli->error;
    }
}

Сега остава да се направи проверка в директория /lang/data , какви файлове има (колко) да се взема информацията от тях (array масиви) в първия пост съм добавил как е масива (той няма променлива ами е чрез return[]) и след това да се обозначи файловото име като short_code за базата данни, за да сработи целия скрипт.
 
Ами… циклиш през всички желани файлове и ги прекарваш през горния код?

Код:
$langs = ['en', 'bg', .... ];
foreach($langs as $lang) {
    $data = include "$lang.php";
    addToDB($data);
}

Най-сигурно е да опишеш ръчно имената на файловете, за да не вземеш да инклуднеш нещо, което не трябва.
Алтернативата е със scandir да вземеш всички файлове и да обходиш тези с имена, завършващи на ".php":

Код:
$files = array_filter(scandir("./path/to/langs/"), function($file) { return substr($file, -4) == ".php"; });

foreach($files as $file) { addToDB(include $file); }
 
Решението:

Код:
<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
$mysqli = new mysqli('localhost','потребител','парола', 'база');
$table_name = "lang_data"; 
$files = array();
foreach (scandir(__DIR__ .'/lang/') as $file) {
	if ($file !=='.' && $file!== '..') {
		$lang = pathinfo($file, PATHINFO_FILENAME);
		$array = require(__DIR__ .'/lang/'.$file);
		foreach ($array as $key => $value) {
    		$sql_I = "insert into $table_name (lang_id, pld_key, pld_data, pld_added) values ('".$lang."', '".mysqli_real_escape_string($mysqli, $key)."', '".mysqli_real_escape_string ($mysqli, $value)."', DATE(NOW()));";
    		if ($mysqli->query($sql_I) === TRUE) {
    			echo $lang."=>> add";
    		} else {
    			echo "err: ".$mysqli->error;
    		}
	    }
    }
}
 
Сега остава да заменя класа, който ползвам за езиците от файлове към база данни.

Структурата на файловете е следната:
<?php
return ['key' => 'value', 'key1' => 'value1',];
?>

Таблицата изглежда така:
pld_id, lang_id, pld_key, pld_data

lang_id = us, gb, de, es, it
pld_key = отговаря на 'key' от масива
pld_data = отговаря на 'value' от масива.

Това ми е класа,
Код:
<?php
class Lang {
	public $current;
	public $default = 'us';
	public $map = [
		'us' => 'us', //United States - English
		'gb' => 'gb', //United Kingdom - English
		'de' => 'de', //Deutsch
		'es' => 'es', //Español
		'it' => 'it', //Italiano
	];
	public $data = [];
	
	private $dir;
	
	public function __construct() {
		$this->dir = ENGINE_DIR . '/data/lang/';
		$this->current = $this->default;
		
		if ( isset($_REQUEST['lang']) && in_array($_REQUEST['lang'], $this->map) ) {
			$this->set($_REQUEST['lang']);
		}
		// Determine the current language
		if ( isset($_COOKIE['lng']) && is_string($_COOKIE['lng']) && array_key_exists($_COOKIE['lng'], $this->map) ) {
			if ( file_exists($this->dir . $this->map[$_COOKIE['lng']] . '.php') ) {
				$this->current = $this->map[$_COOKIE['lng']];
			}
		} elseif ( isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ) {
			$lang = substr(strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']), 0, 2);
			if ( $lang && array_key_exists($lang, $this->map) ) {
				$this->current = $this->map[$lang];
			}
		}
	}
	public function get() {
        if ( file_exists($this->dir . $this->current . '.php') ) {
    		$this->data = require $this->dir . $this->current . '.php';
    		$this->merge();
    		return $this->data;
        } else {
            echo 'Language file not found, contact by administrator';
        }
	}
	
	public function set($lang) {
		$expire = 365 * 86400 + time(); // 1 год
		$domain = str_replace(['http://', 'https://'], '', mb_strtolower($_SERVER['HTTP_HOST'], 'utf-8'));
		if ( substr( $domain, 0, 4 ) == 'www.' ) $domain = substr( $domain, 4 );
	
		setcookie( 'lng', $lang, $expire, '/', $domain, NULL, TRUE );
		$_COOKIE['lng'] = $lang;
	}
	
	private function merge() {
		if ( $this->current != $this->default ) {
		    if ( file_exists($this->dir . $this->default . '.php') ) {
				$this->data = array_merge(require $this->dir . $this->default . '.php', $this->data);
			} else {
			    echo 'Language file not found, contact by administrator';
			}
			
		}
	}
}

Ако някой може, нека удари рамо (между другото може и сам да се оправя, обаче да раздвижиме форума.)

Принципно:
1. проверка на езика дали е в базата данни
2. извикване на данните
3. наливане в масив
4. присвояване/използване на променливата $this->data с данните от базата данни , вместо ($this->data = require $this->dir . $this->current . '.php';)


ЕДИТ: Ако някой има препоръка за правилно ползване или защита на бисквитките , моля нека сподели също мнение
 
Искаш изцяло да се откажеш от системата с файловете, заменяйки я с база от данни, или искаш да поддържаш и двете паралелно?
 
anonimen каза:
Искаш изцяло да се откажеш от системата с файловете, заменяйки я с база от данни, или искаш да поддържаш и двете паралелно?

Изцяло да заменя файловете. Първия вариант.
 
Просто решение.

Код:
<?php
class Lang {
	public $current;
	public $default = 'us';
	public $map = [
		'us' => 'us', //United States - English
		'gb' => 'gb', //United Kingdom - English
		'de' => 'de', //Deutsch
		'es' => 'es', //Español
		'it' => 'it', //Italiano
		'fr' => 'fr', //Français
	];
	public $data = [];
	
	private $dir;
	
	public function __construct() {
		$this->dir = ENGINE_DIR . '/data/lang/';
		$this->current = $this->default;
		
		if ( isset($_REQUEST['lang']) && in_array($_REQUEST['lang'], $this->map) ) {
			$this->set($_REQUEST['lang']);
		}
		// Determine the current language
		if ( isset($_COOKIE['lng']) && is_string($_COOKIE['lng']) && array_key_exists($_COOKIE['lng'], $this->map) ) {
			if ( file_exists($this->dir . $this->map[$_COOKIE['lng']] . '.php') ) {
				$this->current = $this->map[$_COOKIE['lng']];
			}
		} elseif ( isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ) {
			$lang = substr(strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']), 0, 2);
			if ( $lang && array_key_exists($lang, $this->map) ) {
				$this->current = $this->map[$lang];
			}
		}
	}
	public function get() {
		global $db;
        if ( file_exists($this->dir . $this->current . '.php') ) {
			$SArray = $db->query( "SELECT `pld_id`, `pld_key`, `pld_data` FROM `promo_lang_data` WHERE `lang_id` = '" . (string)$this->current . "';" );
			if(mysqli_num_rows($SArray) > 0) {
			    while ($obj = $SArray->fetch_object()) {
			        $rows[$obj->pld_key] = $obj->pld_data;
			    }
    			$this->data = $rows;
        		$this->merge();
        		return $this->data;
			} else {
                die('Language file not found, contact by administrator.');
            }
        } else {
            die('Language file not found, contact by administrator.');
        }
	}
	
	public function set($lang) {
		$expire = 365 * 86400 + time(); // 1 год
		$domain = str_replace(['http://', 'https://'], '', mb_strtolower($_SERVER['HTTP_HOST'], 'utf-8'));
		if ( substr( $domain, 0, 4 ) == 'www.' ) $domain = substr( $domain, 4 );
	
		setcookie( 'lng', $lang, $expire, '/', $domain, NULL, TRUE );
		$_COOKIE['lng'] = $lang;
	}
	
	private function merge() {
		global $db;
		if ( $this->current != $this->default ) {
		    if ( file_exists($this->dir . $this->default . '.php') ) {
    			$SArray = $db->query( "SELECT `pld_id`, `pld_key`, `pld_data` FROM `promo_lang_data` WHERE `lang_id` = '" . (string)$this->default . "';" );
    			if(mysqli_num_rows($SArray) > 0) {
    			    while ($obj = $SArray->fetch_object()) {
    			        $rows[$obj->pld_key] = $obj->pld_data;
    			    }
				    $this->data = array_merge($rows, $this->data);
    			} else {
                    die('Language file not found, contact by administrator.');
                }
			} else {
                die('Language file not found, contact by administrator.');
			}
			
		}
	}
}

Ако, някой може да препоръча някакви подобрение - отворен съм.
 
Четеш папката с файловете, вземаш списъм с тях, отваряш ги един по един, четеш съдържанието и записваш в базата.
Не виждам какво ти е виновен форума ако не се справяш с такива лесни задачи
 
Аз не разбрах къде се запъна със задачката, за това и не съм отговарял. До колкото четох и сам се оправи.

Иначе не смятам, че е добра идея преводите да са ти в базата данни. За всяко нещо ще имаш разходка до базата данни специално да вземеш превод. Ако не замисляш да имплементираш някакъв вид кеширане в паметта, това решение е меко казано лошо.
 
Реших , че може да стане "дискусия". Иначе, да. Кеширах нещата, добавил и други изгъзици и глезотии.
 

Горе