Php подключение к oracle

Обновлено: 02.07.2024

Этот документ описывает, как PHP взаимодействует с базой данных Oracle. Подразумевается, что у Вас уже установлен и настроен PHP. Проверить его работоспособность можно следующим скриптом:

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

В чем разница между модулями OCI и ORA?

В дистрибутив PHP входят два модуля, предназначенных для работы с PHP:

* Стандартные Oracle-функции (ORA)
* Интерфейс для доступа к функциям Oracle (OCI)

Если есть возможность выбора, предпочтение стоит отдать модулю OCI, так как он более оптимизирован и имеет большую функциональность. К примеру, модуль ORA не поддерживает CLOB, BLOB, BFILE, ROWID.

Как собрать PHP с поддержкой Oracle?

;extension = php_oci8.dll
;extension = php_oracle.dll

Также убедитесь в том, чтобы extension_dir указывала на директорию, содержащую указанные модули.

Если у Вас Linux-сервер, пересоберите PHP с одной из опций:

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

Как подключится к базе данных?

Если вы используете модуль OCI, воспользуйтесь следующим кодом:

Если вы используете модуль ORA, попробуйте следующее:

Замечание: если у Вас не установлены необходимые переменные окружения, поместите следующие строки в начале каждого скрипта, работающего с Oracle:

В случае, если Вы несколько раз в пределах одного скрипта попробуете подключится к базе данных, используя одинаковую комбинацию логин/пароль, Вы получите одно и то же соединение. Если Вам необходимы различные подключения к базе, используйте функцию OCINLogon(). Если вам нужны постоянные соединения, используйте функцию OCIPLogon().

Почему возникает ошибка "Call to undefined function: ora_logon()/ ocilogon()"?

Вероятнее всего, у Вас не включена поддержка Oracle. Вернитесь к вопросу "Как собрать PHP с поддержкой Oracle?". Вам необходимо пересобрать php, если у Вас Linux или раскомментировать загрузку соответствующей библиотеки, если у вас Windows.

Как выполнять запросы SELECT, INSERT, UPDATE и DELETE посредством PHP?
Приведенный ниже исходный код демонстрирует, как удалять/создавать новые таблицы, записывать/извлекать из них данные в PHP.

Как получить доступ к механизму транзакций из PHP?

При использовании модуля OCI каждый раз после удачного выполнения ociexecute() автоматически происходит commit, и, таким образом, транзакция сразу же завершается. Вы можете управлять этим процессом, указывая дополнительный параметр OCI_COMMIT_ON_SUCCESS либо OCI_DEFAULT при вызове функции ociexecute(). В случае использования OCI_DEFAULT вы сможете полностью управлять механизмом транзакций, для этого используйте функции OCICommit() и OCIRollback().

Следует учесть, что использование OCI_DEFAULT в одном из вызовов ociexecute() автоматически наследуется для всего подключения к базе данных и будет использовано при дальнейших операциях с базой данных. Если вы не хотите использовать автоматический и ручной механизм управления транзакциями одновременно, используйте OCINLogon().

В случае, если Вы используете модуль ORA, управление транзакциями выглядит немного иначе. Используйте функции ORA_CommitOn() и ORA_CommitOff() для переключения между ручным и автоматическим механизмом управления транзакциями. Для завершения транзакции и отката используйте функции ORA_Commit() и ORA_Rollback() соответственно.

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

Как корректно обрабатывать возникающие ошибки?

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

В случае, если вы используете модуль ORA, воспользуйтесь функциями ora_error() и errorcode() для получения информации о последней произошедшей ошибке.

Как вызвать из PHP хранимую процедуру?

Приведенный ниже пример демонстрирует создание и вызов хранимой процедуры.

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

См. Управление соединением для более детальной информации по управлению соединениями.

Начиная с PHP 5.1.2 (PECL OCI8 1.1) функция oci_close() может использоваться для завершения соединения.

Второй и последующие вызовы функции oci_connect() с теми же параметрами вернут идентификатор уже открытого соединения. Это означает, что транзакции используют одно и то же базовое соединение с базой данных. При необходимости разделения транзакций рекомендуется использовать функцию oci_new_connect() .

Список параметров

Имя пользователя Oracle.

Содержит экземпляр Oracle для подключения. Это может быть » Easy Connect string, или Connect Name из файла tnsnames.ora , или имя локального экземпляра Oracle.

Если не указано отдельно, PHP использует переменные окружения, такие как TWO_TASK (на Linux) или LOCAL (на Windows) и ORACLE_SID для определения экземпляра Oracle для соединения.

Для использования метода Easy Connect, PHP должен быть слинкован с клиентскими библиотеками версии Oracle 10g или старше. Easy Connect string для Oracle 10g принимает следующую форму: [//]host_name[:port][/service_name]. Начиная с Oracle 11g синтаксис таков: [//]host_name[:port][/service_name][:server_type][/instance_name]. Названия служб могут быть определены с помощью запуска Oracle утилиты lsnrctl status на сервере базы данных.

Файл tnsnames.ora может находиться в поисковом пути Oracle Net, который включает $ORACLE_HOME/network/admin и /etc . В качестве альтернативного варианта можно установить TNS_ADMIN таким образом, чтобы путь $TNS_ADMIN/tnsnames.ora был читаемым. Убедитесь, что веб-сервер имеет доступ к этому файлу.

Определяет кодировку, используемую клиентскими библиотеками Oracle. Данная кодировка не обязательно должна совпадать с кодировкой, используемой в самой базе данных. Если она не совпадает, Oracle сделает все возможное для конвертирования данных из- и в данную кодировку. В зависимости от используемых кодировок это может не всегда давать приемлемые результаты. Преобразование также создает некоторые дополнительные временные затраты.

Если кодировка не указана, клиентские библиотеки Oracle будут определять ее из переменной окружения NLS_LANG .

Передача этого параметра может уменьшить время затрачиваемое на соединение.

Этот параметр доступен начиная с версии PHP 5 (PECL OCI8 1.1) и принимает следующие значения: OCI_DEFAULT , OCI_SYSOPER и OCI_SYSDBA . Если были указаны OCI_SYSOPER или OCI_SYSDBA , данная функция попытается установить привилегированное соединение, используя внешние данные авторизации. По умолчанию привилегированные соединения отключены. Чтобы их включить, необходимо установить oci8.privileged_connect в On.

В версии PHP 5.3 (PECL OCI8 1.3.4) появилось значение OCI_CRED_EXT . Оно указывает Oracle использовать внешнюю аутентификацию или аутентификацию с помощью операционной системы, что должно быть настроено в базе данных. Флаг OCI_CRED_EXT может быть использован только с именем пользователя "/" и пустым паролем. oci8.privileged_connect может принимать значение On или Off.

OCI_CRED_EXT может использоваться совместно с режимами OCI_SYSOPER и OCI_SYSDBA .

OCI_CRED_EXT не поддерживается в Windows по причинам безопасности.

Возвращаемые значения

Возвращает идентификатор соединения или FALSE в случае ошибки.

По работе пришлось совершить подключение к базе данных Oracle на PHP. С Oracle раньше работать не приходилось, так что засел за долгое и мучительное гугление. Перелопатив англо- и русскоязычные форумы, Stack Overflow и прочие подобные ресурсы, в итоге получилось добиться результата, но путь был пройден не близкий. Так что, может быть, данная статья кому-нибудь пригодится.
Итак, начну с исходных данных, т.к. подключение к БД Oracle на разных системах и разных версиях PHP отличается. Вот что было у меня:

  • Windows 10, 64-bit;
  • OpenServer 5.2.2 (на других локальных серверах не пробовал, но думаю данное решение подойдет для XAMPP, Denwer и если вы развернете свой локальный сервер);
  • PHP 5.3 (на PHP 5.4 данная инструкция не работает);
  • Apaсру 2.2.

А теперь сделаем подключение к базе данных Oracle

  1. Для начала скачиваем Oracle Instance для версии Windows 32-bit (не спрашивайте, почему 32-bit, я не знаю, но именно так это работает). Версии Oracle Instance 11.2 отсюда (на момент написания статьи актуальная версия Version 11.2.0.4.0). Вам нужно будет зарегистрироваться, чтобы скачать, такая уж политика Oracle.
  2. Создаем на диске C папку instantclient_11_2, в которую разархивируем скачанный Oracle Instance.
  3. Создаем папке instantclient_11_2 папку network, а в ней папку admin и создаем в последней файл tnsnames.ora (тут немного инфы об этом файле). Конченый путь к файлу должен быть такой C:\instantclient_11_2\network\admin\tnsnames.ora. Открываем этот файл через редактор и вставляем следующий код:

MYDB = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = ххх.ххх.ххх.ххх)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ХХХ) ) )

Вот, собственно и все. Теперь можете пробовать подключаться к БД Oracle. Сделать это можно так:

$conn = oci_connect('username', 'password', 'xxx.xxx.xxx.xxx/db_name'); if (!$conn) < $e = oci_error(); trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR); >$stid = oci_parse($conn, 'SELECT * FROM employees); // Выберем все из таблицы employees oci_execute($stid); $row = oci_fetch_array($stid, OCI_BOTH); while ( ( $row = oci_fetch_array( $stid, OCI_BOTH ) ) != false ) < echo $row["ID"]; // Выведем значение ID из таблицы >

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

Как установить связку PHP+Oracle под Windows для чайников

Понадобилось установить на локальные машины связку PHP+Oracle. Промучилась два дня, изображая собою человечка, бьющегося головой о монитор - наконец все заработало. Записываю все ходы и хаки, чтобы потом не забыть (да и мало ли вдруг еще кому пригодится).
Кажется, вся эта информация в сборе собирается и публикуется в одном месте впервые :). Мне пришлось ее выискивать и интегрировать из сотен разных источников :).

Итак, установка связки PHP с Oracle за 10 простых шагов!

1. IP-Адрес и Порт-форвардинг.
- Если за компьютером, на который ставится Oracle не закреплен жестко локальный IP-адрес, заходим в панель управления нашим роутером или каким иным устройством, которое обеспечивает локальную сеть и раздает IP-адреса. Делаем Address reservation. Привязываем жестко текущий IP-адрес машины к ее MAC. На моем роутере TPLink оно в пункте меню DHCP.
- Делаем Port-Forwarding для порта 1521 (на котором будет слушать Oracle listener) для машины, на которую ставится Oracle. Если возможности настроить forwarding нет, то пока откладываем это дело, может оно и так заработает.

3. Проверка связи.
Запускаем из командной строки sqlplus без параметров.
Если пишет кракозябрами вместо русских буковок, есть два варианта решения проблемы:
- Изменить шрифт командной строки с нормального на дурацкий через системное меню окошка, потом вызвать chcp, посмотреть что за кодировка (должна быть 866), вызвать chcp 1251 - должна встать, после чего sqlplus будет общаться по русски, но дурацким шрифтом.
- Изменить язык с русского на английский с помощью regedit:
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_O raDb11g_home1
NLS_LANG AMERICAN_AMERICA.CL8MSWIN1251

Вводим юзера system, пароль (который вводили везде на шаге 2), базу данных (если спросит) orcl.
Если не коннектит, идем биться головой о монитор и гуглить.
Пишем ему connect system/Тот_самый_пароль@orcl
Если коннектит, то все ок. Если не коннектит, идем снова биться головой о монитор и гуглить, гуглить до посинения.

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

4. Настройка Oracle Listener-а для возможности коннектов с других машин в локальной сети.
Идем в директорию %ORACLE%\product\11.2.0\dbhome_1\NETWORK\A DMIN
- Открываем файл listener.ora
Находим строчку
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
и копипаст ее, в копии вместо localhost пишем адрес машины в локальной сети, который мы к ней привязали на шаге 1., например:
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.101)(PORT = 1521))
Должно получить нечто вроде того:

5. Проверка что получилось.
- Идем в Службы Windows.
Находим там службу OracleOraDb11g_home1TNSListener
И перезапускаем ее, чтобы включились новые настройки из listener.ora.

- В командной строке запускаем lsnrctl
Скармливаем ему команду status
Должно получиться нечто вроде того:

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

6. Скачивание InstantClient (Это совсем другая байда, нежели Oracle Database Client, скачанный и установленный на шаге 2!)
Качаем InstantClient отсюда. 32-х разрядный! Так как php - 32-х разрядный - и с x64-InstantClient работать тупо не будет. x64-php для windows - это большая редкость, говорят. Не проверяла, мне достаточно своего родного 32-php. Так что пусть будет все 32-х.

7. Юзаем хак, подробно описанный здесь. Без оного хака php отказывается подключать oci8, сообщая, что-де php_oci8.dll не является приложением Win32 :).
Страничка в интернете вещь ненадежная, поэтому цитирую оттуда самое важное:

1. Unzip Oracle Instant Client 32-bit and move it to C:\WINDOWS\SYSWOW64\INSTANTCLIENT_11_2. You may need to do this in a console with elevated permissions.
2. Edit your PATH environment variable and insert C:\WINDOWS\SYSTEM32\INSTANTCLIENT_11_2 in the directory list before the entry for the Oracle Home library.

Windows makes it so all 32-bit applications that reference C:\WINDOWS\SYSTEM32 actually see the contents of the C:\WINDOWS\SYSWOW64 directory. Your 64-bit database won't find an Instant Client in the real, physical C:\WINDOWS\SYSTEM32 directory and will continue to use the database libraries.

8. Подключение php_oci8
- Раскомментируем в php.ini строчку
extension=php_oci8.dll

- Записываем в переменную окружения PATH X:\php;X:\php\ext; (путь к php у кого какой, "X:\php" для примера) - если оно там вдруг не было записано ранее.
Находится она, PATH, через Панель управления - Система - Дополнительные параметры - Дополнительно - Переменные среды

- Рестартим апачу, смотрим что в error.log. Если там не ругается на oci8 - вызываем из скрипта php echo phpinfo(); и смотрим что пишут про oci8. Если ругается, то гуглим и бьемся головой о монитор :)

9. Проверка связи!
- Мучительно ползем обратно в директорию %ORACLE%\product\11.2.0\dbhome_1\NETWORK\A DMIN и открываем файл tnsnames.ora. Находим там примерно такую ботву:

Жирненьким выделено так называемое имя сервиса (оно, кстати, задается при инсталляции Oracle Database, но я продуплила его изменить, такое вот выросло по умолчанию), которое нам надо тщательно запомнить для дальнейших манипуляций с коннектами.

- Создаем скрипт php примерно такой:

- Запускаем скрипт. Если все ок, то оно так и напишет, что ОК - значит у нас почти все уже, наконец, получилось. А если не ок, то - снова биться головой о монитор и всякое такое, малоэстетичное.

10. Уффф! Теперь бы нам хотелось что-то phpmyadmin-образное для Oracle.
Ползем, совсем уже обалдевшие от всей этой мегаботвы, сюда. Качаем сборку, там один файл .php, ставим под апач, запускаем. Нам показывают формочку для входа.
В System выбираем Oracle.
В Server пишем localhost/orcl.168.1.101
Username - system
Password - понятно что.
Database - оставляем пустым, ничего не пишем туда.
Жмем Login. Если все ок - то любуемся интерфейсом и нутром Oracle в привычной юзер-френдли среде. Если не ок, то ложимся спать, потому что поздно уже, хватит, все, basta, that's enough!

11. Упс! Что-то в 10 шагов не уложились. Разрешение на коннект с Oracle с других машин в локальной сети.
У Windows-а есть брандмауэр. Панель управления - Брандмауэр Windows - Разрешить запуск программ бла-бла. Кнопочка "Разрешить другую программу", затем кнопочка "Обзор". Мучительно ищем по директориям директорию %ORACLE%\product\11.2.0\dbhome_1\BIN. Мучительно находим там файл TNSLSNR.EXE, добавляем, подтверждаем, ок, ок, уффф.

12. Настройка подключения к Oracle с другой машины в локальной сети.
На другой машине:
- Делаем директорию типа C:\Oracle\Instant
- Копируем туда весь InstantClient, добытый на шаге 6.
- Прописываем в PATH C:\Oracle\Instant
- Прописываем туда же в переменные среды, на всякий случай:
TNS_ADMIN=C:\Oracle\Instant
NLS_LANG=Russian_CIS.CL8MSWIN1251 (если не собираемся на этой машине юзать sqlplus, то пусть русский будет, угу).
- Проходим шаг 8. для этой машины.
- Берем наш скрипт, созданный на шаге 9, меняем в нем "localhost/orcl.168.1.101" на "192.168.1.101/orcl.168.1.101" и запускаем.

Если все ок - то ура! Мы, наконец, одержали победу!

Если же все не ок, то, возможно, причина проблемы с Port Forwarding, если мы его не настроили на шаге 1.

Читайте также: