webew
Войти » Регистрация
 
PHP

Вопрос от чайника по типам

23 ноября 2010, 2:51
Автор: NewUse
Я полный чайник в пхп, но как я понял fetchRow() умеет возвращать два различных типа, что не поддерживается php5, скрипт для старой версии php4, помогите, плз, сделать проверку на тип, или как-то ещё устранить ошибку:

Ошбка:
Цитата:
PHP Fatal error: Call to a member function fetchRow() on a non-object in /usr/local/www/data/index.php on line 1


Скрипт:
while ($row = $query->fetchRow()) {
    unset($ROW);
    $row[packet] = "<A HREF=packet.php?gid=$row[gid]>$row[packet]\n";
    $TMP_ROW = "<A HREF=edit_packet.php?gid=$row[gid]><img src=images/edit.gif alt=\"".$INDEX_PAGE[edit]."\" border=0></A>\n";
    if ($row[action] > 0){
            $TMP_ROW.=" | <A HREF=edit_price.php?gid=$row[gid]><img src=images/price.gif alt=\"".$INDEX_PAGE[price]."\" border=0></A>\n";
    }
    $TMP_ROW.=" | <A HREF=del_packet.php?gid=$row[gid]><img src=images/delete.gif alt=\"".$NIBS_TEXT[delete]."\" border=0></A>\n";
    $row[action] = $TMP_ROW;
    $count = $db->getRow("select count($username) as $username from users where gid=$row[gid]");
    $row[num_users] = $count[$username];
    $TOTAL_USER += $count[$username];
    $TRAF_ARRAY = $db->GetRow("select sum(in_bytes) as in_bytes, sum(out_bytes) as out_bytes from ".NIBS_ACCT_TABLE." where gid=".$row[gid]);
    $row[gid] = round($TRAF_ARRAY[in_bytes]/(1024*1024),$ROUND_DIGIT)."/";
    $row[gid].= round($TRAF_ARRAY[out_bytes]/(1024*1024),$ROUND_DIGIT);
    $TOTAL_IN  += $TRAF_ARRAY[in_bytes];
    $TOTAL_OUT += $TRAF_ARRAY[out_bytes];
    while(list($key,$val)=each($row)){
        if ($HEADER){
            $TMP_HEADER[] = array(VARS   => $NIBS_TEXT[$key],
                                  TD_CLR => HDR_CLR,
                                  TH     => true);
        }
        $ROW[] = array(VARS   => $val,
                       TD_PAR => "align=middle",
                       TD_CLR => DEF_CLR);
    }
    if($HEADER){
        $HEADER  = false;
        $ARRAY[] = $TMP_HEADER;
    }
    $ARRAY[]=$ROW;

}

Добавить комментарий
Отображение комментариев: Древовидное | Плоское

paulus

Смотреть надо всё-таки чуть выше в код — там, где определяется $query:
у Вас это не объект, и методов у него нету.
23.11.2010, 11:58
Ответить
NO USERPIC

NewUse

$sql = "SELECT packet, num as num_users,gid,tos as action FROM ".NIBS_PACKETS_TA
BLE." order by num";
$query = $db->query($sql);


Какая версия требовалась -- не знаю MySQL , поставил 5.1 , а что обозначает
".NIBS_PACKETS_TA
BLE."
? Не подскажите, это точное название таблицы, или переменная, а то вполне возможно, что загруженная sql-схема не подходит к этому Веб-Интерфейсу :(
В любом случае не понимаю, почему происходит именно фатальная ошибка, а не простое игнорирование?
23.11.2010, 14:59
Ответить

paulus

1. Скорее всего, в сценарии нету ентера в слове TABLE :)
2. Это не переменная, это макрос, определяется он где-то выше, видимо.
3. $query порождается $db, возможно, у него есть какой-то интерфейс для определения ошибок, посмотрите где-нибудь на его определение.
23.11.2010, 15:52
Ответить
NO USERPIC

NewUse

Да, эта гадость похоже использует некий "движок" ADOdb :(

define ("NIBS_ACCT_TABLE","actions");
define ("NIBS_AUTH_TABLE","users");
define ("NIBS_PACKETS_TABLE","packets");
define ("NIBS_PRICES_TABLE","prices");
define ("NIBS_BLACKLIST_TABLE","blacklist");
define ("NIBS_HOLIDAYS_TABLE","holidays");


include_once("./adodb/adodb.inc.php");

if(!extension_loaded ($NIBS_CONF[db_type]) ){
    echo "Модуль PHP <i>".$NIBS_CONF[db_type]."</i> не загружен.";
    exit();
}else{
    $db = &ADONewConnection($NIBS_CONF[db_type]);
}


Но не понимаю, почему ошибка, вроде же есть нормальная обработка ошибок, или я не правильно понимаю?
if(!$db->Connect($NIBS_CONF[db_host], $NIBS_CONF[db_user], $NIBS_CONF[db_passwor
d], $NIBS_CONF[db_name]) and basename($filename)!="settings.php"){
    echo "Не удалось подключиться к серверу баз данных";
    exit();
}

23.11.2010, 16:03
Ответить

paulus

ADO — штука хорошая, но работает только в виндоус, насколько я знаю. Смотрите, что там внутри написано. Должен быть какой-то метод, который выводит текст ошибки. Его надо вывести и прочитать. Т.е. что-то типа

$query = $db->query($sql);
print $db->error(); // вот тут надо знать правильное имя метода.
23.11.2010, 17:28
Ответить
NO USERPIC

NewUse

На сколько я понял, АДО-- это пхп примочка для сервера, а уж на чём она запущенна -- дело десятое, но в любом случае моя версия для линукса/БСД.....

вот что смог найти

<?php
/**
 * @version V5.00 05 Feb 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
 * Released under both BSD license and Lesser GPL library license.
 * Whenever there is any discrepancy between the two licenses,
 * the BSD license will take precedence.
 *
 * Set tabs to 4 for best viewing.
 *
 * The following code is adapted from the PEAR DB error handling code.
 * Portions (c)1997-2002 The PHP Group.
 */



if (!defined("DB_ERROR")) define("DB_ERROR",-1);

if (!defined("DB_ERROR_SYNTAX")) {
    define("DB_ERROR_SYNTAX",              -2);
    define("DB_ERROR_CONSTRAINT",          -3);
    define("DB_ERROR_NOT_FOUND",           -4);
    define("DB_ERROR_ALREADY_EXISTS",      -5);
    define("DB_ERROR_UNSUPPORTED",         -6);
    define("DB_ERROR_MISMATCH",            -7);
    define("DB_ERROR_INVALID",             -8);
    define("DB_ERROR_NOT_CAPABLE",         -9);
    define("DB_ERROR_TRUNCATED",          -10);
    define("DB_ERROR_INVALID_NUMBER",     -11);
    define("DB_ERROR_INVALID_DATE",       -12);
    define("DB_ERROR_DIVZERO",            -13);
    define("DB_ERROR_NODBSELECTED",       -14);
    define("DB_ERROR_CANNOT_CREATE",      -15);
    define("DB_ERROR_CANNOT_DELETE",      -16);
    define("DB_ERROR_CANNOT_DROP",        -17);
    define("DB_ERROR_NOSUCHTABLE",        -18);
    define("DB_ERROR_NOSUCHFIELD",        -19);
    define("DB_ERROR_NEED_MORE_DATA",     -20);
    define("DB_ERROR_NOT_LOCKED",         -21);
    define("DB_ERROR_VALUE_COUNT_ON_ROW", -22);
    define("DB_ERROR_INVALID_DSN",        -23);
    define("DB_ERROR_CONNECT_FAILED",     -24);
    define("DB_ERROR_EXTENSION_NOT_FOUND",-25);
    define("DB_ERROR_NOSUCHDB",           -25);
    define("DB_ERROR_ACCESS_VIOLATION",   -26);
}

function adodb_errormsg($value)
{
global $ADODB_LANG,$ADODB_LANG_ARRAY;

    if (empty($ADODB_LANG)) $ADODB_LANG = 'en';
    if (isset($ADODB_LANG_ARRAY['LANG']) && $ADODB_LANG_ARRAY['LANG'] == $ADODB_LANG) ;
    else {
        include_once(ADODB_DIR."/lang/adodb-$ADODB_LANG.inc.php");
    }
    return isset($ADODB_LANG_ARRAY[$value]) ? $ADODB_LANG_ARRAY[$value] : $ADODB_LANG_ARRAY[DB_ERROR];
}

function adodb_error($provider,$dbType,$errno)
{
    //var_dump($errno);
    if (is_numeric($errno) && $errno == 0) return 0;
    switch($provider) {
    case 'mysql': $map = adodb_error_mysql(); break;
   
    case 'oracle':
    case 'oci8': $map = adodb_error_oci8(); break;
   
    case 'ibase': $map = adodb_error_ibase(); break;
   
    case 'odbc': $map = adodb_error_odbc(); break;
   
    case 'mssql':
    case 'sybase': $map = adodb_error_mssql(); break;
   
    case 'informix': $map = adodb_error_ifx(); break;
   
    case 'postgres': return adodb_error_pg($errno); break;
   
    case 'sqlite': return $map = adodb_error_sqlite(); break;
    default:
        return DB_ERROR;
    }   
    //print_r($map);
    //var_dump($errno);
    if (isset($map[$errno])) return $map[$errno];
    return DB_ERROR;
}

//**************************************************************************************

function adodb_error_pg($errormsg)
{
    if (is_numeric($errormsg)) return (integer) $errormsg;
    static $error_regexps = array(
            '/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/' => DB_ERROR_NOSUCHTABLE,
            '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/'      => DB_ERROR_ALREADY_EXISTS,
            '/divide by zero$/'                     => DB_ERROR_DIVZERO,
            '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER,
            '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD,
            '/parser: parse error at or near \"/'   => DB_ERROR_SYNTAX,
            '/referential integrity violation/'     => DB_ERROR_CONSTRAINT,
            '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/'    
                 => DB_ERROR_ALREADY_EXISTS
        );
    reset($error_regexps);
    while (list($regexp,$code) = each($error_regexps)) {
        if (preg_match($regexp, $errormsg)) {
            return $code;
        }
    }
    // Fall back to DB_ERROR if there was no mapping.
    return DB_ERROR;
}
   
function adodb_error_odbc()
{
static $MAP = array(
            '01004' => DB_ERROR_TRUNCATED,
            '07001' => DB_ERROR_MISMATCH,
            '21S01' => DB_ERROR_MISMATCH,
            '21S02' => DB_ERROR_MISMATCH,
            '22003' => DB_ERROR_INVALID_NUMBER,
            '22008' => DB_ERROR_INVALID_DATE,
            '22012' => DB_ERROR_DIVZERO,
            '23000' => DB_ERROR_CONSTRAINT,
            '24000' => DB_ERROR_INVALID,
            '34000' => DB_ERROR_INVALID,
            '37000' => DB_ERROR_SYNTAX,
            '42000' => DB_ERROR_SYNTAX,
            'IM001' => DB_ERROR_UNSUPPORTED,
            'S0000' => DB_ERROR_NOSUCHTABLE,
            'S0001' => DB_ERROR_NOT_FOUND,
            'S0002' => DB_ERROR_NOSUCHTABLE,
            'S0011' => DB_ERROR_ALREADY_EXISTS,
            'S0012' => DB_ERROR_NOT_FOUND,
            'S0021' => DB_ERROR_ALREADY_EXISTS,
            'S0022' => DB_ERROR_NOT_FOUND,
            'S1000' => DB_ERROR_NOSUCHTABLE,
            'S1009' => DB_ERROR_INVALID,
            'S1090' => DB_ERROR_INVALID,
            'S1C00' => DB_ERROR_NOT_CAPABLE
        );
        return $MAP;
}

function adodb_error_ibase()
{
static $MAP = array(
            -104 => DB_ERROR_SYNTAX,
            -150 => DB_ERROR_ACCESS_VIOLATION,
            -151 => DB_ERROR_ACCESS_VIOLATION,
            -155 => DB_ERROR_NOSUCHTABLE,
            -157 => DB_ERROR_NOSUCHFIELD,
            -158 => DB_ERROR_VALUE_COUNT_ON_ROW,
            -170 => DB_ERROR_MISMATCH,
            -171 => DB_ERROR_MISMATCH,
            -172 => DB_ERROR_INVALID,
            -204 => DB_ERROR_INVALID,
            -205 => DB_ERROR_NOSUCHFIELD,
            -206 => DB_ERROR_NOSUCHFIELD,
            -208 => DB_ERROR_INVALID,
            -219 => DB_ERROR_NOSUCHTABLE,
            -297 => DB_ERROR_CONSTRAINT,
            -530 => DB_ERROR_CONSTRAINT,
            -803 => DB_ERROR_CONSTRAINT,
            -551 => DB_ERROR_ACCESS_VIOLATION,
            -552 => DB_ERROR_ACCESS_VIOLATION,
            -922 => DB_ERROR_NOSUCHDB,
            -923 => DB_ERROR_CONNECT_FAILED,
            -924 => DB_ERROR_CONNECT_FAILED
        );
       
        return $MAP;
}

function adodb_error_ifx()
{
static $MAP = array(
            '-201'    => DB_ERROR_SYNTAX,
            '-206'    => DB_ERROR_NOSUCHTABLE,
            '-217'    => DB_ERROR_NOSUCHFIELD,
            '-329'    => DB_ERROR_NODBSELECTED,
            '-1204'   => DB_ERROR_INVALID_DATE,
            '-1205'   => DB_ERROR_INVALID_DATE,
            '-1206'   => DB_ERROR_INVALID_DATE,
            '-1209'   => DB_ERROR_INVALID_DATE,
            '-1210'   => DB_ERROR_INVALID_DATE,
            '-1212'   => DB_ERROR_INVALID_DATE
       );
       
       return $MAP;
}

function adodb_error_oci8()
{
static $MAP = array(
             1 => DB_ERROR_ALREADY_EXISTS,
            900 => DB_ERROR_SYNTAX,
            904 => DB_ERROR_NOSUCHFIELD,
            923 => DB_ERROR_SYNTAX,
            942 => DB_ERROR_NOSUCHTABLE,
            955 => DB_ERROR_ALREADY_EXISTS,
            1476 => DB_ERROR_DIVZERO,
            1722 => DB_ERROR_INVALID_NUMBER,
            2289 => DB_ERROR_NOSUCHTABLE,
            2291 => DB_ERROR_CONSTRAINT,
            2449 => DB_ERROR_CONSTRAINT
        );
       
    return $MAP;
}

function adodb_error_mssql()
{
static $MAP = array(
          208 => DB_ERROR_NOSUCHTABLE,
          2601 => DB_ERROR_ALREADY_EXISTS
      );
       
    return $MAP;
}

function adodb_error_sqlite()
{

static $MAP = array(
          1 => DB_ERROR_SYNTAX
       );
       
    return $MAP;
}

function adodb_error_mysql()
{
static $MAP = array(
           1004 => DB_ERROR_CANNOT_CREATE,
           1005 => DB_ERROR_CANNOT_CREATE,
           1006 => DB_ERROR_CANNOT_CREATE,
           1007 => DB_ERROR_ALREADY_EXISTS,
           1008 => DB_ERROR_CANNOT_DROP,
           1045 => DB_ERROR_ACCESS_VIOLATION,
           1046 => DB_ERROR_NODBSELECTED,
           1049 => DB_ERROR_NOSUCHDB,
           1050 => DB_ERROR_ALREADY_EXISTS,
           1051 => DB_ERROR_NOSUCHTABLE,
           1054 => DB_ERROR_NOSUCHFIELD,
           1062 => DB_ERROR_ALREADY_EXISTS,
           1064 => DB_ERROR_SYNTAX,
           1100 => DB_ERROR_NOT_LOCKED,
           1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
           1146 => DB_ERROR_NOSUCHTABLE,
           1048 => DB_ERROR_CONSTRAINT,
            2002 => DB_ERROR_CONNECT_FAILED,
            2005 => DB_ERROR_CONNECT_FAILED
       );
       
    return $MAP;
}
?>


но я правда чайник :(((

23.11.2010, 19:16
Ответить

paulus

adodb_error похожа на близкую по смыслу функцию. Но — ей надо передать код ошибки. Теперь ищите место, откуда можно достать этот код :(
23.11.2010, 20:08
Ответить
NO USERPIC

NewUse

Цитата:
Теперь ищите место, откуда можно достать этот код :(

не очень понял ответ, какой код? на сколько я смог просмотреть
query($sql)
должна выводить ошибку.... или я не так понял?

Вызывается она одинажды, да и то хитро (в условии цикла,я не знаю, что означает синтаксис)
while ($row = $query->fetchRow())
(с.м. первое сообщение)
23.11.2010, 20:47
Ответить

paulus

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

Это идеальный случай. В Вашем случае — вы нажимаете на кнопку на автомате, а выпадает не банка, а кирпич. Вы пытаетесь дернуть крючок на кирпиче, и тут происходит ошибка. Проблема не в query, проблема в db, который выдает кирпич вместо query.
23.11.2010, 20:59
Ответить
NO USERPIC

NewUse

Ну то ли я не понял аналогии, то ли не понимаю причины ошибки, но ошибка (почти на 100%) именно в отсутствии соотв. записи в БД, но почему она критическая? по идеи должен был быть штатный механизм обхода таких ситуаций..... но похоже его нет....

Собственно вопрос,
Правильно ли я понял причину ошибки:
происходит запрос на данные масива, который должен был бы быть получен из БД, но т.к. записи в БД отсутствуют -- возвращается ошибка(имеющая другой тип), проверка выхода из цикла пытается сравнить разные типы данных, или просто натыкается, допустим на String вместо Boolean что вызывает ошибку, от сюда вопрос, как эту ошибку проигнорировать, очевидно, надо добавить проверку на тип перед входом в цикл,и перед выходом из него, но я не знаю синтаксиса, или я не прав, и это всё полная чушь, и я ничерта не понял?

Цитата:
у или не знаю, как назвать это колечко

ну открывалкой, например :)

вот что смог ещё найти:

    function Query($sql, $inputarr=false)
    {
        $rs = $this->Execute($sql, $inputarr);
        if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
        return $rs;
    }


и

    function DB()
    {
    global $_ADODB_ACTIVE_DBS;
   
        if ($this->_dbat < 0) {
            $false = false;
            $this->Error("No database connection set: use ADOdb_Active_Record::SetDatabaseAdaptor(\$db)", "DB");
            return $false;
        }
        $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
        $db = $activedb->db;
        return $db;
    }


23.11.2010, 21:12
Ответить

paulus

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

Если хотите просто добавить проверку на то, что вернулся объект — можете сделать что-то типа
if($query) {
... // тут обработка, если вернулся объект
}


Но лучше понять, из-за чего возникает ошибка, и устранить причину. К сожалению, из того, что Вы написали, я понять причину не могу. Кстати, а нельзя связаться с разработчиком сценария?
23.11.2010, 23:11
Ответить
NO USERPIC

NewUse

Цитата:
Но лучше понять, из-за чего возникает ошибка, и устранить причину.

именно это я и пытаюсь осознать...
это Веб-морда к бесплатной билинговой системе
Система представляет собой модуль к серверу аутентификации FreeRADIUS
Всё Открытое, но разработка прекращена в 2004 г., автор похоже забросил своё деяние :(((
Те релизы, что я ковыряю:
http://sourceforge.net/projects/freesnibs/files/freesnibs/freenibs-2.2.3/freenibs-2.2.3.tar.bz2/download
(это сам модуль, в нём ничего инерессного (с точки зрения пхп), кроме папки shemas, в которой лижит скелет БД мускула ), я его переделал под мускул5 (просто поменяв синтаксис)

Веб-морда, ещё более старая, но есть чужая переработка от 2007г:
http://sourceforge.net/projects/adminibs/files/adminibs/webnibs/webnibs_20070417.rar/download

Цитата:
Если хотите просто добавить проверку на то, что вернулся объект — можете сделать что-то типа

Помогите, пожалуйста, я же писал, что ПОЛНЫЙ чайник :((
Я до сих пор не понимаю смысла конструкции
$row = $query->fetchRow()

:( т.е. что передаётся функции fetchRow или к чему она применяется ?
И какой тип от результата $query ожидается?
Помогите составить конструкцию:
Если $query не соответствует ожидаемому типу, -- распечатать $sql и $query как текст (на текущую веб-станицу) и перейти к метке (если язык позволяет безусловный переход) или составить соответствующую сложную конструкцию, к условию цикла while, опять таки, если позволяет язык...
Это во-первых перестанет приводить к фатальной ошибки, а, во вторых позволит найти её причину....

возможно ли что-то типа:

while ( is_object ($query) &&($row = $query->fetchRow()) {

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

криво, но пхп многое прощает, как я понял....
24.11.2010, 00:28
Ответить

paulus

Обычно достаточно просто дописать print($sql): такая отладка — дело одноразовое.
Да, можете написать именно так (в php даже есть конструкция is_object ;) ).
24.11.2010, 11:24
Ответить
NO USERPIC

NewUse

блин, ничерта не понимаю: вылетает из-за этого запроса:
SELECT packet, num as num_users,gid,tos as action FROM packets order by num


из-за чего может быть ошибка для БД MySQL5?

функция FetchRow
  function FetchRow()
    {
        if ($this->EOF) {
            $false = false;
            return $false;
        }
        $arr = $this->fields;
        $this->_currentRow++;
        if (!$this->_fetch()) $this->EOF = true;
        return $arr;
:
24.11.2010, 16:49
Ответить
NO USERPIC

NewUse

Всё, разобрался, ошибка была в скелете БД :(((

при ручном вводе sql запроса БД ругалась:
Цитата:
ERROR 1054 (42S22): Unknown column 'num' in 'field list'

помогло добавление столбца:

ALTER TABLE packets ADD num INT
24.11.2010, 19:40
Ответить

1234ru

Не знаю, насколько этот совет в данном случае поможет, но посмотрите сюда: http://webew.ru/articles/3237.webew
То, что не убивает нас, делает нас инвалидами.
23.11.2010, 22:33
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2017 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100