Способы хранения информации php

Хранение данных в текстовых файлов с использованием РНР

Любой крупный проект требуется длительного хранения информации. Частично можно решить данную проблему с помощью данных Cookie. Однако данное решение имеет ряд недостатков, поэтому информацию следует хранить в более безопасном месте с ограниченным доступом, например на сервере.

Сохраняться информация может в текстовых файлах или в базе данных. Текстовые файлы хранятся в локальной файловой системе. Их можно прочитать с помощью команд операционной системы и редактировать любым доступным способом. Информация в файлах обычно хранится в строковой форме.

Для использовании баз данных требуется установить специализированное программное обеспечение, например MySQL. Базы данных тоже представляют собой файлы, которые, однако, создаются соответствующими приложениями и могут быть доступны только через них.

При использовании баз данных необходимо иметь навыки работы с соответствующим программным обеспечением. Например, для получения нужной информации достаточно правильно сформулировать запрос на языке SQL, чтобы система управления базами данных обработала этот запрос и предоставила результат. При этом абсолютно не важно, где и в каком виде хранится требуемая информация.

Приведем преимущества использования текстовых файлов по сравнению с базами данных. I

Простота и гибкость. Нам не нужно устанавливать дополнительное программное обеспечение для работы с базами данных. Достаточно создать файл средствами РНР и хранить в нем полезную информацию. Кроме того, текстовые файлы можно обрабатывать во многих текстовых редакторах или электронных таблицах.

Экономия дискового пространства. Текстовые файлы занимают гораздо меньше дискового пространства, чем базы данных.

Текстовые файлы являются простым и эффективным с точки зрения использования ресурсов способом хранения небольших объемов информации. Они просты в использовании и обеспечивают быстрый доступ к данным. Текстовые файлы доступны для всех, кто обладает правами на доступ к требуемому каталогу, поэтому их можно использовать в качестве средства обмена информацией.

Базы данных, кроме обеспечения безопасности на уровне операционной системы, предоставляют дополнительный уровень защиты. Также база данных обладает поддержкой сложной структуры данных, различными типами данных и взаимосвязями. Это позволяет существенно упростить поиск и извлечение требуемой информации.

Еще одним преимуществом использования баз данных является поддержка многопользовательского режима, который обеспечивает согласованность данных и предотвращает опасность их затирания или потери. Все это достигается значительно большим используемым дисковым пространством.

Существует также и встроенная база данных SQLite, которая устанавливается вместе с интерпретатором PHP и предназначена для использования файлов и баз данных. При использовании расширения SQLite информация хранится в текстовых файлах, однако для доступа к ним применяется стандартный язык запросов SQL. Расширение SQLite удобно использовать для хранения и обработки небольших объемов данных, однако для организации большого хранилища данных все же лучше воспользоваться специализированными пакетами.

Использование текстовых файлов

При их использовании текстовых файлов не нужно устанавливать дополнительное программное обеспечение. Для чтения или записи в файл достаточно воспользоваться соответствующими операторами языка РНР.

Обработка тестовых файлов происходит в 3 этапа:

1. Открытие файла.

2. Запись или извлечение данных из файла.

3. Закрытие файла.

Для выполнения операций над файлом его необходимо открыть. Для этого предназначена функция Fopen, общий синтаксис которой:
Переменная $fh является дескриптором файла (file handle), который используется при чтении или записи данных в файл. Дескриптор файла содержит информацию о местоположении открытого файла.

Для определения действий, которые будут выполнятся над файлом после его открытия, необходимо указать соответствующий режим. Опишем основные режимы:

r‘ — Только чтение. Если файл не существует, выводится предупреждающее сообщение.

r+‘ — Чтение и запись. Если файл не существует выводится предупреждающее сообщение.

w‘ — Только запись. Создается новый файл. Если файл существует, новый файл полностью перезаписывает содержимое.

w+‘ — Чтение и запись. Создается новый файл. Если файл существует, новый файл полностью перезаписывает содержимое.

a‘ — Добавление данных в конец файла. Если файл не существует, создается новый файл.

a+‘ — Чтение и добавление данных в конец файла. Если файл не существует, создается новый файл.

Параметр ‘имя_файла’ должен содержать имя файла (filename.txt), полный путь к нему (с:/localhost/filename.txt) или адрес URL (http://site.com/filename.txt).

Открытие файла в режиме чтения

Открыть файл и считать из него информацию поможет функция Fopen со следующими общими параметрами:
В результате интерпретатор РНР выполнит поиск файла ‘file.txt‘ в текущем каталоге, в котором расположен сценарий РНР. Если файл не существует, может быть выведено сообщение об ошибке:
Вывод предупреждения не приведет к прерыванию выполнения сценария, поэтому, чтобы избежать некорректной работы, в случае отсутствия файла воспользуйтесь функцией Exit, которая прерывает выполнение сценария и выводит заданное сообщение:
Открытие файла в режиме записи
Открыть файл в заданном каталоге в режиме записи можно воспользовавшись следующим выражением:
Если заданный файл не существует, будет создан новый файл. Однако, если отсутствует требуемый каталог, будет выведено сообщение об ошибке:
Проверить существование каталога можно следующим образом:
Теперь открытие файла будет выполняться только в том случае, если существует требуемый каталог.

Открытие файла на другом Web-узле

Если файл размещен на другом Web-узле, его можно открывать только в режиме для чтения:
Закрытие файла

После использования файла его обязательно нужно закрыть функцией Fclose:
В качестве входного параметра функция использует дескриптор файла $fh, который ранее был создан при его открытии.

Для записи в файл различной информации предназначена функция Fwrite со следующим общим синтаксисом:
Параметрами этой функции являются дескриптор файла $fh, созданный при его открытии, и данные, которые необходимо сохранить. В качестве данных можно использовать текстовую строку или переменную. Например:
В этом фрагменте файл открывается для добавления информации. Если при открытии файла не существовало, будет создан новый файл. При этом данные будут записаны в его первую строку. При открытии существующего файла текущая информация добавляется в конец файла.

Гораздо удобнее размещать различную информацию в отдельных строках. Для этого функцию Fwrite нужно вызвать таким образом:
Если в файл нужно добавить информацию, его необходимо открыть в режиме ‘а‘. При открытии в режиме записи файл каждый раз будет создаваться заново, а информация — перезаписываться.

Для чтения файла предназначена функция Fgets со следующим синтаксисом:
где $fh — дескриптор файла, который был создан при его открытии. Функция Fgets считывает файл до тех пор, пока не будет достигнут конец строки или файла. В указанном примере информация сохраняется в переменной $line. Построчно можно прочитать весь файл. Для определения конца файла в языке РНР предназначена функция Feof. В сле­дующем примере считываются и выводятся все строки файла:
Функция Feof возвращает значение TRUE при достижении конца файла с дескриптором $fh. Восклицательный знак в условном выражении цикла While обеспечивает чтение всех строк файла.

Символ перевода строки используется функцией Fgets по умолчанию. В некоторых случаях этого не требуется, так что эти символы нужно удалить:
Функция Rtrim удаляет пробелы в конце строки и символы перевода строки. Так что при ее использовании будет получен следующий результат в одну строку.

Чтение файлов по частям

Для считывания строки определенного размера следует использовать функцией Fgets со следующим синтаксисом:
В данном случае строка длиной n-1 будет считываться до тех пор, пока не будет достигнут конец строки или файла. Например:
В приведенном фрагменте считываются каждые десять символов, пока не будет достигнут конец файла. Обратите внимание, что после каждой строки по умолчанию используется символ перевода строки.

Читайте также:  Классический способ накрутки волос

Размещение файла в массиве

Разместить содержимое всего файла в массиве можно следующим образом:
В результате будет создан массив $content, ключами которого будут целые числа, а значениями — строки, считанные из файла.

То же самое можно осуществить с помощью одной функции File. При этом получится аналогичный результат:
Функция File открывает файл, размещает строки в массиве $content и закрывает файл. Следует следить за объемом использованной памяти, поскольку, если открываемый файл очень большой, то использование функций File может существенно замедлить работу сценария. Для ускорения быстродействия, где это возможно, вместо функции File следует пользоваться функцией Fgets.

Размещение файла в строке

Содержимое файла можно разместить в одной длинной строке. Для этого предназначена функция File_get_contents:
Функция File_get_contents полностью аналогична File, за исключением того, что содержимое файла размещается не в массиве, а в строке. Символы перевода строки входят в состав результирующей строки $content и, естественно, учитываются при выводе.

Обмен данными с другими программами

Благодаря использованию файлов, можно обеспечить взаимодействие сценариев РНР с другими приложениями. Практически все без исключения программы предоставляют возможность считывания или записи данных в файл и последующим взаимодействием с другими приложениями.

Для работы с файлами необходимо точно знать формат сохранения информации. В сценарии РНР такой формат можно сгенерировать с помощью функции Fwrite.

Файлы CSV (Comma-Separated Values — значения, разделяемые запятой), иногда называемые также файлами с символами-разделителями, (comma-delimited file), являются стандартным средством обмена данными между различными приложениями. Файлы CSV могут использоваться для обмена информацией, содержащейся в таблице (со столбцами и строками) и используется текстовыми редакторами, например OpenOffice Calc. Формат CSV достаточно распространен и поддерживается различным программными обеспечением.

CSV-файл имеет следующую структуру: каждая его строка соответствует строке таблицы, а значения, разделенные запятой, — столбцам. Рассмотрим следующий пример легковых автомобилей, организованной с использованием файла CSV:
OpenOffice Calc позволяет прочитать этот файл и преобразовать его в таблицу, состоящую из трех столбцов. При этом запятая используется в качестве символа-разделителя.

Следующий фрагмент кода на языке РНР позволяет создать файл в формате CSV.
Для чтения CSV-файла можно воспользоваться функцией File или Fgets. Однако специально для этих целей в языке РНР имеется функция Fgetcsv, которая при чтении файла каждую строку записывает в массив, элементами которого являются значения столбцов. Например:
В приведенной строке из файла с идентификатором $fh считывается строка длиной
1000 символов. Результатом выполнения функции Fgetcsv будет следующий массив:
Формат CSV очень удобно использовать при передаче данных между различными приложениями. Однако не забывайте о том, что если символ ‘,’ является частью данных, то его нельзя использовать в качестве символа-разделителя.

Источник

Способы хранения динамических данных

Построение многоязычных приложений – это очень многогранная проблема, которая не имеет единого эффективного решения и подразумевает индивидуальный подход в каждом конкретном случае. В данном материале я предполагаю изложить свои взгляды на возможные варианты работы с динамическим многоязычным контентом.

Несколько слов о статическом контенте

Несомненно, помимо динамического контента, есть еще и статический. Что мы к таковому отнесем? В первую очередь – сообщения наших скриптов: это могут быть какие-то сообщения об ошибках (например, пользователь неправильно заполнил форму), также, мы можем давать пользователю какие-то подсказки, есть еще определенный набор текста, которы выводится в том или ином случае, и который не меняется.

Один из способов, который я, в частности, использую – это связка PHP и GetText. Подробнее об этом вы можете прочитать здесь: http://php.russofile.ru или в 12 номере журнала PHPInside (http://phpinside.ru). Существует еще несколько способов обработки статического многоязычного контента, но они не являются объектом данной статьи.

Несколько слов о различных кодировках

Кодировок очень много, скажем, для русского можно назвать 3 наиболее распространенных: DOS (866), windows-1251, KOI8-R. Такая же ситуация, возможно, справедлива и для других языков, поэтому здесь необходима некоторая стандартизация. В нашем материале мы будем все языковые ресурсы хранить в кодировке UNICODE, а именно – в UTF-8. Также будут рассмотрены разнообразные манипуляции с кодировками.

Необходимо помнить, что когда мы говорим о разнообразии языков, мы не считаем английский и все языки, чей символьный диапазон попадает под кодировку latin1. Дело в том, что latin1 часть присутствует во всех кодировках и есть всегда, а, следовательно, смысла считать ее отдельным языком нет. Пример, русская кодировка windows-1251 содержит в себе и латинские символы, при этом никаких перекодировок делать не надо.

Вводная часть на этом закончена и мы переходим к основной части нашего повествования.

Составляющие динамического контента

Что может являться динамическим контентом? Это те материалы вашего сайта, которые подвержены частичному или полному изменению с достаточной степенью периодичности: новости, статьи, голосования и так далее. Надо полагать, что структура этих данных неоднородна, как по объему информации, так и по степени динамичности. Также, мы не должны упускать из виду тот факт, что отдельные динамические элементы сайта могут быть общими для всех его языковых версий, а какие-то – уникальны для каждого варианта.

Таким образом, вы видите, что данная проблема очень многоплановая, а, следовательно, есть несколько путей решения.

Давайте введем, для лучшего понимания, несколько терминов (их придумал я, поэтому не ожидайте тут сверх четкой и гладкой формулировки).

Уникальный контент – этим термином мы будем называть контент, который уникален для каждой языковой версии сайта.

Общий контент – этим термином мы будем называть контент, который актуален для всех языковых версий одновременно.

Рассуждения о типах контента

Прежде чем задумываться о способах хранения контента, необходимо определить для себя, какой контент у вас является уникальным, а какой – общим.

Давайте посмотрим, что же можно отнести к уникальному контенту?

Как правило, языковые версии сайта редко полностью совпадают друг с другом. Дерево разделов сайта часто отличается и причем значительно. Следовательно, названия разделов будут у нас уникальны и хранить мы будем их отдельно для разных языковых версий сайта. Отдельность хранения вовсе не означае, что мы будем использовать разные базы данных, просто для хранения каждого элемента у нас будет своя запись в базе данных – сколько элементов – столько записей. И лишь двухбуквенный индекс (например, ‘ru’, ‘en’, ‘pl’ и др.) будет сигнализировать нам к какой языковой версии сайта эта запись относится.

Поскольку дерево разделов у нас уникально для каждого сайта, значит и страницы с контентом будут также уникальны, а, следовательно, с хранением этих данных у нас также проблем не будет.

Что может относиться к общему контенту? Например, иллюстрации, на которых не нанесен никакой текст, скажем, фотографии. Ведь при выводе на разных языковых версиях сайта иллюстрациям необходимо дать какое-то описание. Это могут быть и голосования, и товары вашего магазина, и так далее. И все эти данные одновременно могут быть представлены сразу на всех языковых версиях. То есть «общим» мы называем контент, который практически без изменений показывается на всех языковых версиях сайта.

Читайте также:  Хранение желудей по способу

Здесь и начинаются разные трудности и разнообразие подходов, о которых мы поговорим ниже.

Как хранить уникальный контент

Уникальность этого контента в том, что он вовсе не обязан присутствовать во всех языковых версиях сайта.

Если это информационный сайт, каждая страница которого достаточно объемна, то логично хранить такие данные в обычных файлах: 1 файл – одна страница. Тем самым мы с вами избегаем путаницы в языковых версиях (при таком подходе у каждой страницы будет свой уникальный идентификатор), а также даем простоту редактирования таких файлов.

Это также облегчает нам процесс работы с кодировками – ведь мы сохраняем с вами текст так, как он есть и нет никакой необходимости задумываться о его формате.

Такой способ хранения информации лучше всего подходит, на мой взгляд, для большого объема информации, хотя вполне в файлах можно хранить, например, ленту новостей.

Используем базу данных

С базами данных, как вы понимаете, все сложнее. Здесь перед нами во всю ширь встает проблема кодировок и совмещения разных языковых данных.

К счастью, на большинстве хостинговых площадок на сегодняшний день установлены базы данных, нормально воспринимающих формат UNICODE, в частности, кодировку UTF-8, а это значит, что, до определенной степени, наша с вами проблема будет решаться проще.

Первое, что мы для себя определяем, так это то, что при хранении разноязыковых данных мы будем использовать кодировку UTF-8. Во-первых, это позволит нам избежать создания множества таблиц для хранения однородных данных, во-вторых, все языковые данные будут в определенной степени унифицированы, а это значит, что с ними будет проще работать. В частности, немаловажен тот факт, что поиск по нашим ресурсам будет организовываться значительно проще.

Поскольку мы сейчас говорим об уникальном контенте, то хранение его в базе мало чем отличается от хранения в файлах. Мы создаем таблицу, которая будет содержать в себе все необходимые поля, переводим наш контент в UTF-8, если он еще не был в этой кодировке, и помещаем в базу стандартными средствами. На каждый элемент контента у нас будет 1 запись в базе.

Перевести контент из любой кодировки в UTF-8 можно следующим образом:

Здесь константа BROWSER_CHARSET содержит название кодировки, в которой ваши данные будут выводиться на экран, например Windows-1251. UTF-8 – указывает в какой кодировке мы хотим получить результат, а переменная $string содержит контент, который мы переводим из одной кодировки в другую.

Если поменять первый и второй аргумент местами, получите обратный результат.

Iconv – это расширение PHP, проверьте, установлено ли оно у вас. Если вы работаете со статическим контентом при помощи GetText, iconv у вас установлен. Если нет – то обратитесь к статье, указанной в первой части этого материала, там описана установка iconv. На большинстве встреченных мною хостинговых площадках эта утилита установлена, так что никаких проблем у вас не будет.

Все это хорошо, но применять такую конструкцию каждый раз по ходу скрипта несколько утомительно и неэффективно, давайте напишем 2 функции, которые будут проделывать эту процедуру.

Давайте разберемся, что делают наши функции. Как следует из их названия, первая подготавливает строки для базы, а вторая подготавливает строки для вывода их в браузер.

Помимо функций я привел еще одну константу и массив. Для чего они нам нужны?

Константа BASE_CHARSET задает кодировку, в которой мы будем хранить информацию в базе (в нашем примере – UTF-8).

Массив $GLOBALS[‘site_languages’] содержит в себе данные по каждому языку: ‘ключ’ – двухбуквенное сочетание каждого языка (для его идентификации), его мы будем использовать везде, где необходимо обозначить язык данных; и значения: [0] – полное название языка, [1] – кодировка, в которой информация будет выводиться в браузер и [2] – идентификатор языка для утилиты GetText.

Эти данные будут нужны нам постоянно, потому мы их оформили так, чтобы они были доступны в каждой функции и во всех классах нашего приложения.

Теперь давайте посмотрим, что делают непосредственно наши две функции.

При вызове каждой из функций в качестве параметра мы передаем КЛЮЧ (см. описание массива $GLOBALS[‘site_languages’]) – двухбуквенное сочетание для языка, на котором написан текст в $string. Второй параметр – это текстовая строка на языке, обозначенном в $lang.

Первым делом функции проверяют – а не совпадает ли кодировка базы данных с кодировкой, в которой мы с вами выводим информацию на экран. Если совпадает, то ничего делать не надо – данные и так в нужной нам кодировке, например, в данном случае кодировка базы и кодировка данных будет совпадать. Если они не совпадают, то производим перекодирование данных. После того, как функция отработает, она вернет готовый для работы результат. Пример работы функций:

И в том и в другом случае в переменной $string окажутся нужные (подготовленные) вам данные. Остается только поместить их в базу.

Незабывайте создавать в базе поле-указатель на язык, куда заносите двухбуквенное сочетание языка, на котором написано ваше сообщение.

Общий контент

Многоязыковые данные небольшого объема

Для начала предлагаю обратить свое внимание на объем текста, который нам необходимо сохранить. Для примера возьмем изображение. Как правило, описание иллюстрации – это небольшой по объему текст, ведь мы будем писать его в atl HTML тега , или просто подписывать иллюстрацию. Обычно для этого хватает 100 – 255 символов. Если предположить, что наш сайт говорит на 5 языках, то общий объем текста максимально составит 1,5 килобайта. В связи с чем, мы принимаем решение хранить все это в базе в одном поле типа TEXT.

Разумеется, мы каким-то образом должны отделить данные для разных языков друг от друга. Для этого мы выработаем решение о разработке определенного формата хранения данных в этом поле.

Я предлагаю следующий способ:

Мы выбрали определенное сочетание знаков, которое врядли может встретиться в обычном тексте. Каждая языковая строка будет предваряться сочетанием КЛЮЧА (двухбуквенного сочетания языка) и знаков :=, а сами сообщения будут разделяться двойной тильдой (

). После того, как строка оформлена указанным способом, мы посылаем ее в базу данных.

Какие преимущества дает нам такой способ хранения данных? Во-первых, данные на любом языке у нас всегда под рукой, во-вторых, сохраняется возможность поиска, причем поиск мы можем вести средствами базы данных и сразу на всех имеющихся языках, поскольку языковые данные у нас не деформируются и находятся в доступной форме.

Теперь давайте напишем еще 3 функции, которые облегчат нам формирование «упакованной» строки указанного формата, а также обеспечат легкость получения данных из «упакованной» строки. В своей работе эти функции будут опираться на первые две, которые даны выше, поскольку финальный результат должен удовлетворять требованию, что результат должен быть полностью готов к употреблению.

Первая функция. Ее задача принять массив определенного формата и сформировать на его основе строку указанного формата.

В данном примере появится еще одна константа – это DEFAULT_LANG. Данная константа определяет, какой язык принят за язык поумолчанию, то есть, на каком языке будет «говорить» сайт, если пользователь в данный момент не указал своего языка.

В качестве параметра эта функция принимает массив следующего вида:

Где lang1 и lang2 – это двухбуквенное сочетание языка, на котором написан string (например, array(‘en’ => ‘english’, ‘ru’ => ‘русский’)) . В результате работы функции вы получите строку в кодировке UTF-8 вида en:=english

Читайте также:  Физические способы воздействия угроз это

В результате своей работы функция вернет вам строку нужного формата или ошибку. Ошибка возникнет тогда, когда вы передали функции массив строк, который не содержит данных на языке поумолчанию. Дело в том, что для нормального функционирования сайта необходимо, чтобы хотябы один из вариантов языковых данных был заполнен, иначе может возникнуть ситуация, когда пользователь не увидит ничего.

И так, функция, которая формирует «упакованную», строку написана и отработала, вы получили нужные вам данные и можете спокойно поместить их в базу. При таком подходе помечать запись в базе двухбуквенным кодом языка не надо, потомучто запись будет содержать сразу все языковые данные.

Может возникнуть ситуация, когда вы внезапно добавили в проект еще один язык. Из дальнейших примеров вы увидите, что подобный способ хранения данных не вызовет никаких трудностей с добавлением нового языка.

Переходим к следующей функции. Ее задача – восстановить «упакованный» массив, который обработала первая функция.

В качестве параметра наша функция принимает «упакованную» строку. В результате ее работы вы получите восстановленный массив, формат которого описан выше.

И, наконец, третья функция, которая позволит быстро и эффективно получать нужные языковые данные, при этом она будет обеспечивать некоторый сервис. Сервисные функции будут заключаться в том, что в случае, когда вы запрашиваете строку на языке, на котором ее не вводили, она вернет вам строку на языке поумолчанию (вот он нам и пригодился). То есть, если вам нужен текст на английском, языком поумолчанию у вас является русский, и строки на английском языке нет – вы получите строку на русском языке. Таким образом, добавление нового языка в проект не вызовет сбоев сайта. Просто временно, пока вы не введете строки на новом языке, они будут выдаваться на языке поумолчанию.

В качестве параметра функция принимает все ту же «упакованную» строку из базы. В результате вы получите сообщение на нужном вам языке в нужной кодировке.

Очень важно помнить, что если вы выводите информацию в браузер в кодировке отличной от UTF-8, последняя функция даст сбой в том случае, если язык по умолчанию у вас не английский. Это произойдет потому, что кодировка, скажем, русского языка может не совпадать с китайской или испанской кодировкой – в такой кодировке просто нет русских символов. В таком случае вы должны каким-то образом предусмотреть подобный вариант и решить самим, что для вас в данном случае будет лучше. Вы всегда можете определить языком поумолчанию английсикй, при этом проблемы с кодировками не возникнет (см. пункт «Несколько слов о различных кодировках»).

Как отмечено выше, возможности поиска также сохраняются. Искать в таких данных вы можете командой LIKE. Разумеется, придется ограничить поисковый текст символами %, например, ‘%поиск%’.

Многоязыковые данные большого объема

В предыдущей части мы рассмотрели с вами возможности по хранению небольших объемов многоязычных данных. Давайте посмотрим, какие варианты у нас есть для хранения относительно больших данных.

Прежде всего, давайте внимательно посмотрим на сами данные. Скажем, для примера, мы возьмем с вами новости, предположим, что они у нас появляются синхронно на всех сайтах. Из чего она может состоять?

  • id – уникальный идентификатор;
  • date_start – дата публикации;
  • date_stop – дата, по достижении которой, новость убирается с главной страницы и помещается в архив;
  • visibe – признак видимости новости на сайте;
  • subject – тема новости (заголовок);
  • short_body – короткий вариант новости;
  • full_body – полный вариант новости;

Для наших исследований такой структуры будет достаточно. Совершенно очевидно, что у каждой языковой версии поля id, date_start, date_stop и visible будут одинаковыми и нам нет никакой необходимости их дублировать. У нас есть несколько вариантов решения проблемы.

Первый вариант – создать в таблице, наряду с общими полями, отдельные поля под каждую языковую версию. У этого подхода есть один недостаток – при добавлении в проект нового языка мы столкнемся с тем, что нам придется расширять нашу таблицу, добавляя к ней новые поля. Не всегда это можно сделать безболезненно и могут возникнуть отдельные проблемы, такие же проблемы возникнут при удалении какого-либо языка из проекта. К тому же, это просто неудобно. А что делать, с новостями, которые были добавлены значительно раньше добавления нового языка и, следовательно, тексты к которым для данного языка отсутствуют? Также могут возникнуть трудности с поиском (в том случае, если вы попытаетесь искать сразу во всех языковых версиях сайта) – поиск даст значительную нагрузку на сервер и, думается, будет достаточно медленным, потомучто вместо 1 поля придется обрабатывать Х*колличество языков полей. Разумеется, любую проблему можно решить, но я предлагаю пойти другим путем.

Во втором варианте я предлагаю разделить нашу новость на две таблицы. Первая таблица будет содержать общие данные, а вторая – языковые.

Давайте посмотрим, как будут выглядеть наши таблицы:

Таким образом, на каждую запись из первой таблицы у нас может быть сколько угодно записей во второй таблице. У всех этих записей будет одинаковый news_id, но разный идентификатор языка news_lang.

В результате, нам совершенно нестрашно добавление любого языка в наш проект, поскольку таблицы никак не зависят от количества языков.

Давайте посмотрим, каким образом можно работать с этой связкой таблиц.

Попробуем выбрать новости для главной страницы русской версии сайта.

Жирным шрифтом я выделил основные связывающие элементы.

NOW() в данном случае означает сегодняшнюю дату, например, вы можете ее получить следующей PHP командой: date(‘Y-m-d’).

Таким образом, если вы только что добавили к своему проекту китайскую версию, но не сделали перевода новостей для это версии, ничего выведено не будет, так как в базе не будет записи с буквенным кодом ‘zh’ (это код китайского языка).

Несмотря на то, что мы сейчас с вами говорили о новости, это будет справедливо к любому динамическому контенту вашего сайта, будь то новости, голосования, или что-то другое. Главное, что вам нужно сделать, это выделить из структуры контента части, которые являются общими (одинаковыми для всех языковых версий) и собственно языковые данные.

Поиск по данным такой структуры организуется очень просто, потому что каждая запись содержит уникальный номер общих данных (news_id) и произведя поиск по тексту новости вы всегда будете знать к какой новости этот текст принадлежит. К тому же поиск будет вестись только по одному полю для всех языковых версий сайта.

Для большей наглядности давайте попробуем с вами вызвать на редактирование русский вариант новости с номером 10.

А теперь вызовем на редактирование все языковые варианты новости с номером 10.

Думаю, что примеры довольно наглядны. В дальнейшем, предлагаю вам поэкспериментировать самим.

Подведем итоги

В этой статье я затронул проблемы хранения многоязычного динамического контента. Мы свами научились разделять «уникальный» динамический контент и «общий», узнали о нескольких способах хранения многоязычных данных, а также рассмотрели проблемы работы с различными кодировками.

Надеюсь, что этот материал будет вам полезен и поможет в разработке ваших приложений.

Я жду любых вопросов и предложений относительно данной статьи. Если вы с чем-то не согласны или наооборот, считаете, что статью надо расширить по каким-то вопросам, – пишите, я рад каждому письму.

Источник

Оцените статью
Разные способы