• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Funktion: Rueckgabewert will nicht ;)

Mad Dog

Mitglied
hey leute,

also ich habe mir hier eine variable select funktion gebastelt (die noch nicht fertig ist).
momentan teste ich denn fall, das aus einer tabelle, jede spalte selctiert werden soll, wenn die email adresse uebereinstimmt.

jetzt hackt es bei mir aber leider beim fetch(). mir scheint als verstehe ich den befehl noch nicht ganz.

hier der relevante teil der funktion:
Code:
            if (!($this->mysqli_stmt->prepare($sql)))
            {
                return FALSE;
            }
            // Variablen einbinden
            else if (!call_user_func_array(array($this->mysqli_stmt, 'bind_param'), &$tmp))
            {            
                return FALSE;
            }
            // Ausfuehren
            else if (!($this->mysqli_stmt->execute()))
            {
                return FALSE;
            }
            else if (!call_user_func_array(array($this->mysqli_stmt, 'bind_result'), $back))
            {
                return FALSE;
            }
            else
            {
                            while ($this->mysqli_stmt->fetch()) 
                            {
                                foreach($back as $key => $value)
                            {
                            $this->return[] = $value;
                            }    
                            }    
                            return true;
            }

als query erstellt mir die funktion folgendes sql statement:
SELECT * FROM user WHERE mail = ?

es werden insgesamt 6 werte ausgelesen:
id
name
pass
ip
email
sessionid

wenn ich mir jetzt die return variable ausgeben lasse:
Code:
foreach ($test->return as $key => $value)
{
    echo $key.' => '.$value.'<br />';
}

erhalte ich folgendes ergebniss:
Code:
0 => afergthyafergthyafergthyafergthy
1 => afergthyafergthyafergthyafergthy
2 => afergthyafergthyafergthyafergthy
3 => afergthyafergthyafergthyafergthy
4 => afergthyafergthyafergthyafergthy
5 => afergthyafergthyafergthyafergthy
 
Werbung:
Poste bitte komplettere Beispiele. Das ist so nur mühsam nachvollziehbar und testbar.

PHP:
<?php

class Foo
{
    protected $mysqli = null;
    protected $mysqli_stmt = null;

    public function __construct()
    {
        $this->mysqli = new mysqli("localhost", "user", "pass", "db");
    }

    public function f($sql, array $tmp)
    {
        $this->mysqli_stmt = $this->mysqli->stmt_init();

        if (!($this->mysqli_stmt->prepare($sql))) {
            return false;
        }

        // Variablen einbinden
        if (!call_user_func_array(array($this->mysqli_stmt, 'bind_param'),
                $this->getReferences($tmp))) {
            return false;
        }

        // Ausfuehren
        if (!($this->mysqli_stmt->execute())) {
            return false;
        }
        
        $back = array('id' => null, 'name' => null, 'pass' => null, 'ip' => null,
                      'email' => null, 'sessionid' => null);        

        if (!call_user_func_array(array($this->mysqli_stmt, 'bind_result'),
                $this->getReferences($back))) {
            return false;
        }

        while ($this->mysqli_stmt->fetch()) {
            var_dump($back);
        }

        return true;
    }

    /**
     *
     * @see http://www.php.net/manual/en/mysqli-stmt.bind-param.php#100051
     * @see http://www.php.net/manual/en/mysqli-stmt.bind-result.php#99175
     * @param array $arr
     * @return array
     */
    protected function getReferences(array &$arr)
    {
        $refs = array();
        
        foreach($arr as $key => $value) {
            $refs[$key] = &$arr[$key];
        }
        
        return $refs;
    }
}

header('Content-Type: text/plain');

$foo = new Foo();
$foo->f("SELECT * FROM user WHERE mail = ?", array('s', '[email protected]'));
 
hey

sorry, dachte die teile wuerden reichen.
hier nochmal der rest

Code:
    public function select($row, $table, $con, $values, $option)
    {
        $sql = 'SELECT';
        
        if ((isset($option['ALL'])) AND ($option['ALL'] === TRUE)) { $sql .= ' ALL'; }
        if ((isset($option['DISTINCT'])) AND ($option['DISTINCT'] === TRUE)) { $sql .= ' DISTINCT'; }
        if ((isset($option['DISTINCTROW'])) AND ($option['DISTINCTROW'] === TRUE)) { $sql .= ' DISTINCTROW'; }
        if ((isset($option['HIGH_PRIORITY'])) AND ($option['HIGH_PRIORITY'] === TRUE)) { $sql .= ' HIGH_PRIORITY'; }
        if ((isset($option['STRAIGHT_JOIN'])) AND ($option['STRAIGHT_JOIN'] === TRUE)) { $sql .= ' STRAIGHT_JOIN'; }
        if ((isset($option['SQL_SMALL_RESULT'])) AND ($option['SQL_SMALL_RESULT'] === TRUE)) { $sql .= ' SQL_SMALL_RESULT'; }
        if ((isset($option['SQL_BIG_RESULT'])) AND ($option['SQL_BIG_RESULT'] === TRUE)) { $sql .= ' SQL_BIG_RESULT'; }
        if ((isset($option['SQL_BUFFER_RESULT'])) AND ($option['SQL_BUFFER_RESULT'] === TRUE)) { $sql .= ' SQL_BUFFER_RESULT'; }
        if ((isset($option['SQL_CACHE'])) AND ($option['SQL_CACHE'] === TRUE)) { $sql .= ' SQL_CACHE'; }elseif (((isset($option['SQL_NO_CACHE'])) AND ($option['SQL_NO_CACHE'] === TRUE))) { $sql .= ' SQL_NO_CACHE';}
        if ((isset($option['SQL_CALC_FOUND_ROWS'])) AND ($option['SQL_CALC_FOUND_ROWS'] === TRUE)) { $sql .= ' SQL_CALC_FOUND_ROWS'; }
        
        // SELECT Teil des statement
        if (!empty($row))
        {
                if ((is_string($row)) AND (trim($row === '*')))
            {
                $sql .= ' *';
            }
            else if (is_string($row))
            {
                     $escapedAttr = $this->real_escape_string($row);
                
                    $sql .= ' FROM '.$escapedAttr;               
            }
            else if (is_array($row))
            {
                // Attributsnamen säubern
                $escapedAttr = array_map(array($this, 'real_escape_string'), array_values($row));
          
                // Attribute einfuegen
                $sql .= ' '.implode(', ', $escapedAttr). ''; 
            } 
            else
            {
                return FALSE;
            }
        }
        else
        {
            return FALSE;
        }        
        
        // FROM Teil des statements
        if (!empty($table))
        {
            if (is_string($table))
            {
                $escapedTable = $this->real_escape_string($table);
                
                $sql .= ' FROM '.$escapedTable;
            }
            else if (is_array($table))
            {
                // Tabelen säubern
            $escapedTables = array_map(array($this, 'real_escape_string'), array_values($table));
            
            // Tabelen einfügen
            $sql .= ' FROM '.implode(', ', $escapedTables). '';
            }
            else
            {
                return FALSE;    
            }
        }
        else
        {
            return FALSE;
        }
        
        // WHERE Teil des statements
        if ((!empty($con)) AND (!($con === FALSE)))
        {
            if (is_string($con))
            {
                $escapedCondition = $this->real_escape_string($con);
                
                $sql .= ' WHERE '.$escapedCondition;                
            }
            else if (is_array($con))
            {
            // Bedingungen säubern
            $escapedConditions = array_map(array($this, 'real_escape_string'), array_values($con));
        
            $sql .= ' WHERE '.implode(' AND ', $escapedConditions). ''; 
          }
          else
          {
              return FALSE;    
          }
        }       
        
       
        if (trim($row === '*'))
        {
            $back = array();
            $empty = '';
            for($i = 0; $i < $option['AMOUNT']; $i++)
            {
                $back[$i] = &$empty;
            }        
        }
        else
        {
            $back = array();
            for ($i = 0; $i < count($row); $i++)
            {
                $back[$i] = '';
            }        
        }
                 
        if ((!empty($con)) AND (!empty($values)))
        {
            // Type für bind_param 
            $type = '';
            $values = array($values);
            for ($i = 0; $i < count($values); $i++)
            {
                if (is_string($values[$i]))
                {
                    $type .= 's'; 
                }
                else if (is_double($values[$i]))
                {
                    $type .= 'd';
                }
                else if (is_int($values[$i]))
                {
                    $type .= 'i';
                }
                else
                {
                    $type .= 'b';
                } 
            }
            
            // Array zusammen quätschen
            $array = array_merge((array)$type, $values);
            $tmp = array();
            foreach($array as &$value) 
            {
                $tmp[] = $value;
            }                   
        }
        
        $this->ssql = $sql;
        
        if ((empty($con)) AND (empty($values)))
        {
            // SELECT vorbereiten
            if (!($this->mysqli_stmt->prepare($sql)))
            {
                return FALSE;
            }
            // Ausfuehren
            else if (!($this->mysqli_stmt->execute()))
            {
                return FALSE;
            }
            else if (!call_user_func_array(array($this->mysqli_stmt, 'bind_result'), &$back))
            {
                return FALSE;
            }
            else
            {
                while ($this->mysqli_stmt->fetch())
                {
                    $this->return[] = $back;
                }
                return true;
            }
            if($this->error) 
            {
                $this->_error->mysqlDie($this->error);
            }        
        }
        else
        {        
            // SELECT vorbereiten
            if (!($this->mysqli_stmt->prepare($sql)))
            {
                return FALSE;
            }
            // Variablen einbinden
            else if (!call_user_func_array(array($this->mysqli_stmt, 'bind_param'), &$tmp))
            {            
                return FALSE;
            }
            // Ausfuehren
            else if (!($this->mysqli_stmt->execute()))
            {
                return FALSE;
            }
            else if (!call_user_func_array(array($this->mysqli_stmt, 'bind_result'), $back))
            {
                return FALSE;
            }
            else
            {
                            while ($this->mysqli_stmt->fetch()) 
                            {
                            $this->return[] = $back;
                            }    
                            return true;
            }
            if($this->error) 
            {
                $this->_error->mysqlDie($this->error);
            }
        }

    }
das problem ist, dass die funktion funktionieren soll, auch wenn mehr oder weniger als 6 spalten selectiert werden sollen.

EDIT:
ich habe die funktion teilweise getestet.
diese sql syntax SELECT name FROM user WHERE mail =? ist gar kein problem, der rueckgabewert passt. auch wenn 2 spalten selectiert werden sollen ist das kein problem.
nur wenn man alles spalten bzw * selectieren moechte, funktioniert das mit dem rueckgabewert nicht...
 
Zuletzt bearbeitet:
Werbung:
Die Funktion hat

- eine Länge von mehr als 150 Zeilen (SLOC),
- mit 5 undokumentierten Eingabeparametern,
- mit insgesamt eher schwacher Dokumentation,
- mit einer cyclomatic complexity von 61 (Quelle: McCabe's cyclomatic complexity)
- sowie mindestens 5 referenzierten, aber undeklarierten Membervariablen, die teilweise Objekte sind und die Seiteneffekte erzeugen.

Wenn ich das Ding testen wollte, müsste ich etliche Zeit dafür aufwenden, überhaupt einen Kontext zu schaffen (sprich: Code nachzubauen, wie schon in #2), der das Testen ermöglicht. Dieser Kontext würde dann sicherlich nicht deinem Kontext entsprechen, was später zu Problemen führen könnte.

Zudem müsste ich mir mühsam aus dem Code erschließen, was die einzelnen Parameter bedeuten und welche Art von Inhalt sie erwarten.

Dann könnte der Fehler noch immer nicht in der Funktion liegen, sondern in der Art und Weise, wie du diese Funktion einsetzt, und alles wäre umsonst gewesen.

Du musst als Fragesteller mehr Testkontext/Informationen zur Verfügung stellen, denn du kannst nicht erwarten, dass das, was ich gerade beschrieben habe, jemand tut.

Das Problem hängt eventuell damit zusammen, wie $back deklariert wird.

PHP:
if (trim($row === '*')) {
        $back = array();
        $empty = '';
        for ($i = 0; $i < $option['AMOUNT']; $i++) {
            $back[$i] = &$empty;
        }
    } else {
        $back = array();
        for ($i = 0; $i < count($row); $i++) {
            $back[$i] = '';
        }
    }

Da scheint irgendein $option['AMOUNT'] benötigt zu werden.
 
Zurück
Oben