Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
146 views
in Technique[技术] by (71.8m points)

php - Create dynamic number Of variables

EDIT: after discussing here click here i decided to use Francis Avila solution, it is securer, but I didn't find a way to exploit my way, only everybody says its security risk to use eval(). If you find a way, to exploit my way, please post a comment. :-), so that i understand it and also another users, who use eval :-)

One more thing not to use eval(), it is slower, for what i wanted todo.

EDIT:

One positive thing, also is in Francis Avila solution is, you need only specific only 2 vars, $SQL + $INPUT, no need more brother with $output.

EDIT: removed the old question and replaced it with this, so you have maybe a better idea what i want to do.

i found a solution how to make a dynamic number of Variables, but its not the optimal solution. Cause i need to edit / add more lines, if the number of variables gets higher than 8. So is there a way, to make that dynamic on dont relay on the switch function

public function readDB($readdb, $input, $output1) {

    $sql = $readdb;
    $stmt = $this->mysqli->prepare($sql);
    if(!empty($input) && is_array($input)) {
        $inputn = count($input);

        switch($inputn) {
            case "1":
                $stmt->bind_param('s', $input[0][0]);
                break;
            case "2":
                $stmt->bind_param('ss', $input[0][0], $input[1][0]);
                break;
            case "3":
                $stmt->bind_param('sss', $input[0][0], $input[1][0], $input[3][0]);
                break;
            case "4":
                $stmt->bind_param('ssss', $input[0][0], $input[1][0], $input[3][0], $input[4][0]);
                break;
            case "5":
                $stmt->bind_param('sssss', $input[0][0], $input[1][0], $input[3][0], $input[4][0], $input[5][0]);
                break;
            case "6":
                $stmt->bind_param('ssssss', $input[0][0], $input[1][0], $input[3][0], $input[4][0], $input[5][0], $input[6][0]);
                break;
            case "7":
                $stmt->bind_param('sssssss', $input[0][0], $input[1][0], $input[3][0], $input[4][0], $input[5][0], $input[6][0], $input[7][0]);
                break;  
            case "8":
                $stmt->bind_param('ssssssss', $input[0][0], $input[1][0], $input[3][0], $input[4][0], $input[5][0], $input[6][0], $input[7][0], $input[8][0]);
                break;
            default:
                break;
        }
    }
    if (!$stmt) {throw new Exception($mysqli->error);}
    $stmt->execute();
    $stmt->store_result();
    $checker = $stmt->num_rows;
    if($checker !== 0) {
        if(!empty($output1)) {
            switch($output1) {
                case "1":
                    $stmt->bind_result($output[0]);
                    while ($stmt->fetch()) {
                        $results[] = array($output[0]);
                    }
                    break;
                case "2":
                    $stmt->bind_result($output[0], $output[1]);
                    while ($stmt->fetch()) {
                        $results[] = array($output[0], $output[1]);
                    }
                    break;
                case "3":
                    $stmt->bind_result($output[0], $output[1], $output[2]);
                    while ($stmt->fetch()) {
                        $results[] = array($output[0], $output[1], $output[2]);
                    }
                    break;
                case "4":
                    $stmt->bind_result($output[0], $output[1], $output[2], $output[3]);
                    while ($stmt->fetch()) {
                        $results[] = array($output[0], $output[1], $output[2], $output[3]);
                    }
                    break;
                case "5":
                    $stmt->bind_result($output[0], $output[1], $output[2], $output[3], $output[4]);
                    while ($stmt->fetch()) {
                        $results[] = array($output[0], $output[1], $output[2], $output[3], $output[4]);
                    }
                    break;
                case "6":
                    $stmt->bind_result($output[0], $output[1], $output[2], $output[3], $output[4], $output[5]);
                    while ($stmt->fetch()) {
                        $results[] = array($output[0], $output[1], $output[2], $output[3], $output[4], $output[5]);
                    }
                    break;
                case "7":
                    $stmt->bind_result($output[0], $output[1], $output[2], $output[3], $output[4], $output[5], $output[6]);
                    while ($stmt->fetch()) {
                        $results[] = array($output[0], $output[1], $output[2], $output[3], $output[4], $output[5], $output[6]);
                    }
                    break;  
                case "8":
                    $stmt->bind_result($output[0], $output[1], $output[2], $output[3], $output[4], $output[5], $output[6], $output[7]);
                    while ($stmt->fetch()) {
                        $results[] = array($output[0], $output[1], $output[2], $output[3], $output[4], $output[5], $output[6], $output[7]);
                    }
                    break;
                default:
                echo "HERE";
                    break;
            }
        }
    } else {
        $results = "NO RESULTS";
    }
    $stmt->fetch();
    $stmt->close();

    $this->checker = $checker;
    $this->results = $results;

    $this->result = array('num_rows' => $checker, $results);

    return $this->results;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you are not in too deep, I highly recommend you use PDO instead of MySQLi because the MySQLi API is terrible.

What you want is actually very difficult. Here's a function which demonstrates the hoops you need to jump through:

function query(MySQLi $db, $sql, array $data) {
    $stmt = $db->prepare($sql);
    if (!$stmt) return null;
    $types = str_repeat('s', count($data));
    $args = array(); // references to values in $data for call_user_func_array
    foreach ($data as $k => $v) {
        $args[$k] =& $data[$k];
    }
    array_unshift($args, $types);
    call_user_func_array(array($stmt, 'bind_param'), $args);
    $stmt->execute();
    // mysqlind driver
    if (method_exists($stmt, 'get_result')) {
        $res = $stmt->get_result();
        $rows = $res->fetch_all(MYSQLI_ASSOC);
        $res->free();
    } else { // by hand, ugh!
        $rows = array();
        $resultbinds = array(); // where results will end up
        $args = array(); // references to $resultbinds for call_user_func_array
        $meta = $stmt->result_metadata();
        while ($fieldmeta = $meta->fetch_field()) {
            $resultbinds[$fieldmeta->name] = null;
            $args[] =& $resultbinds[$fieldmeta->name];
        }
        $meta->free();
        call_user_func_array(array($stmt, 'bind_result'), $args);
        while ($stmt->fetch()) {
            $row = array();
            // copy array to dereference
            foreach ($resultbinds as $k => $v) {
                $row[$k] = $v;
            }
            $rows[] = $row;
        }
    }
    $stmt->free_result();
    $stmt->close();
    return $rows;
}

This is how you would do the same thing in PDO:

function query_PDO($db, $sql, $data) {
    $stmt = $db->prepare($sql);
    $stmt->execute($data);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $stmt->closeCursor();
    return $rows;
}

Here is how to connect to MySQL using PDO:

function connect_PDO() {
    $host = 'localhost';
    $user = 'root';
    $pass = 'root';
    $dbname = 'scratch';
    $port = 8889;
    $socket = '/Applications/MAMP/tmp/mysql/mysql.sock';
    $options = array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    );
    if (version_compare(PHP_VERSION, '5.3.6', '<')) {
        $options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES utf8';
    }
    $dsn = "mysql:host={$host};port={$port};unix_socket={$socket};dbname={$dbname};charset=utf8";
    return new PDO($dsn, $user, $pass, $options);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...