oracle — команда php system (), которая вызывает sqlplus, приводит к зависанию php

У меня есть простой скрипт PHP, который вызывает файл sqlplus sqlldr и сбрасывает данные в таблицу в Oracle. Я сузил проблему до того, что, по моему мнению, является причиной зависания моего php-скрипта … который:
Когда я запускаю из php CLI, системная команда не возвращается к php, скорее она зависает в sqlplus land. При запуске из браузера скрипт работает должным образом, и я получаю последнюю команду echo, которая печатает в браузере: Я закончила бегать сейчас.

<?PHP
system('sqlplus username/password@tnsNameOfDatabase',$out);
echo $out;
system('exit',$out);
echo $out;
echo 'I am done running now';

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

SQL*Plus: Release 12.1.0.2.0 Production on Wed Mar 8 15:37:34 2017

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Last Successful login time: Wed Mar 08 2017 15:37:18 -05:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning and Oracle Label Security options

сейчас … проблема в том, что моя php-программа зависает, и я больше не могу вернуться к php-скрипту. Как выйти из CLI sqlplus, чтобы вернуться к работающему php-скрипту?

Типичная команда выхода в SQLPLUS — просто ‘exit’, и я попробовал это (как вы можете видеть выше) … что при запуске вручную приводит к следующему:

Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning and Oracle Label Security options

Как мне выйти из sqlplus и вернуться в сценарий, который должен продолжаться? Любая помощь очень ценится!


Фактический метод, который вызывает этот скрипт sqlplus и снова — прекрасно работает при вызове из браузера, но при вызове из CLI он зависает прямо здесь, в этом методе, прежде чем он возвращается.

private function loadTempData($object) {
$this->getLog()->appendLogFile('Constructed Control File: '.$object->getTempData()->getQaveLoadControl()->getFullPathFileName());
$this->getLog()->appendLogFile('Result saved in: '.$object->getTempData()->getExportFile()->getFullPathFileName());
$object->getInsertCommandFile()->appendContent('$ sqlldr '.$this->getPersistEnv()->getUserSlid().'/'.$this->getPersistEnv()->getPassword().'@'.$this->getPersistEnv()->getDatabase().' control='.$object->getTempData()->getQaveLoadControl()->getFullPathFileName().' log='.$object->getTempData()->getQaveLoadControl()->getFullPathFileName().'.log');
$this->getLog()->appendLogFile('Loading data to Temp Table');
$command = 'sqlplus '.$this->getPersistEnv()->getUserSlid().'/'.$this->getPersistEnv()->getPassword().'@'.$this->getPersistEnv()->getDatabase().' @'.$object->insertCommandFile->getFullPathFileName();
$this->getLog()->appendLogFile($command);
system($command,$output);
// this line does not make it into the log...
$this->getLog()->appendLogFile($output);
// this method does not return when run from CLI
return true;
}

0

Решение

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

<?php
$credentials = escapeshellarg("username/password@tnsNameOfDatabase");
$scriptfile = escapeshellarg("@/my/sqlldr/file");
exec("sqlplus $credentials $scriptfile", $output, $return);
// $output contains every line of output from the program, as an array
// $return contains the numeric exit code from the program
echo 'I am done running now';

Наконец, убедитесь, что вы даете команду программе выйти с действительным оператором «EXIT» в вашем файле SQL, как вы обнаружили!

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]