Asked  7 Months ago    Answers:  5   Viewed   46 times

I am using the entries of a db to fill a row and a column in a table. But I cannot access the SQL returned data twice using mysqli_fetch_array() twice. This doesn't work:

//Copy the result
$db_res = mysqli_query( $db_link, $sql );
$db_res2=$db_res;

//Top row
while ($row = mysqli_fetch_array( $db_res, MYSQL_ASSOC))
{
        echo "<td>". $row['Title'] . "</td>";
}

//leftmost column
while ($row = mysqli_fetch_array( $db_res2, MYSQL_ASSOC))
{
                    echo "<tr>";
        echo "<td>". $row['Title'] . "</td>";
                    .....
                    echo "</tr>";
}

How can I apply mysqli_fetch_array twice on the same result?

 Answers

60

You don't need the while loop and you don't need to use mysqli_fetch_array() at all.

You can simply loop on the mysqli_result object itself many times.

//Top row
foreach($db_res as $row) {
    echo "<td>". $row['Title'] . "</td>";
}

//leftmost column
foreach($db_res as $row) {
    echo "<tr>";
    echo "<td>". $row['Title'] . "</td>";
    .....
    echo "</tr>";
}

However, you should separate your DB logic from your display logic and to achieve this it is best to use fetch_all(MYSQLI_ASSOC) in your DB logic to retrieve all records into an array.

Wednesday, March 31, 2021
 
Corne
answered 7 Months ago
52

The code you provided works for me.

The call_user_func_array(...) function just calls the bindParam or bind_result methods on the $query object with the given array, as if you had provided each element of the array as a method argument.

You may want to check the SQL statement you are having the problem with, with the code below. I've rewritten it a bit in order to make it fully testable, since the original code depends on the statement class in your abstraction layer.

<?php

$db_host = 'localhost';
$db_user = 'username';
$db_pass = 'password';
$db_name = 'database';

$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);

print_r(fetchRows('SELECT something from some_table WHERE some_id = ?', 'i', 1));

function traceVar($a, $b) {
    print_r(array($b => $a));
}

function fetchRows(){
        error_reporting(E_ALL+E_NOTICE);
        $args = func_get_args();
        $sql = array_shift($args);
        traceVar($sql, "Query");

        // Keep the column types for bind_param.
        // $colTypes = array_shift($args);

        // Column types were originally passed here as a second
        // argument, and stored in the statement object, I suppose.
        if (!$query = $GLOBALS['mysqli']->prepare($sql)){ //, $colTypes)) {
                die('Please check your sql statement : unable to prepare');
        }
        if (count($args)){
                traceVar($args,'Binding params with');

                // Just a quick hack to pass references in order to
                // avoid errors.
                foreach ($args as &$v) {
                    $v = &$v;
                }

                // Replace the bindParam function of the original
                // abstraction layer.
                call_user_func_array(array($query,'bind_param'), $args); //'bindParam'), $args);
        }

        $query->execute();

        $meta = $query->result_metadata();
        while ($field = $meta->fetch_field()) {
                $params[] = &$row[$field->name];
        }
        traceVar($params,'Binding results with');
        call_user_func_array(array($query, 'bind_result'), $params);

        while ($query->fetch()) {
                traceVar($row,'After fetch');
                $temp = array();
                foreach($row as $key => $val) {
                        $temp[$key] = $val;
                } 
                $result[] = $temp;
        }

        $meta->free();
        $query->close(); 
        //self::close_db_conn(); 
        return $result;
}
Wednesday, March 31, 2021
 
elias
answered 7 Months ago
29

I've thrown together a simple demo on jsfiddle here showing how to do this with @font-face: http://jsfiddle.net/zMKge/

Opera also has a simple tutorial on using <canvas>, including the text API.

CSS:

@font-face {
    font-family: 'KulminoituvaRegular';
    src: url('http://www.miketaylr.com/f/kulminoituva.ttf');
}

Javascript:

var ctx = document.getElementById('c').getContext('2d');
var kitty = new Image();
kitty.src = 'http://i954.photobucket.com/albums/ae30/rte148/891blog_keyboard_cat.gif';
kitty.onload = function(){
  ctx.drawImage(this, 0,0,this.width, this.height);
  ctx.font         = '68px KulminoituvaRegular';
  ctx.fillStyle = 'orangered';
  ctx.textBaseline = 'top';
  ctx.fillText  ('Keyboard Cat', 0, 270);
};
Sunday, June 27, 2021
 
jenny
answered 4 Months ago
80

You need to iterate through the result set returned by MySQL. That means calling mysqli_fetch_array() for each row of that result set. You can do that using a while loop:

while($row = mysqli_fetch_assoc($result)) {
    $rows[] = array("name"      => $row['name'],
                    "city"      => $row['bill_city'],
                    "code"      => $row['bill_code'],
                    "country"   => $row['bill_country'],
                    "street"    => $row['bill_street'],
                    "latitude"  => $row['latitude'],
                    "longitude" => $row['longitude'],
                    "type"      => $row['setype']);
    }
}
Tuesday, July 27, 2021
 
Karsten
answered 3 Months ago
43

WebGL's blend modes do not include multiplication (of the source and destination), either. However, you can perform the multiply operation efficiently using WebGL's render-to-texture capabilities:

  1. Let your visible canvas be a WebGL canvas.
  2. Create two textures; call them "source" and "destination".
  3. Render your invisible-canvas content to the "source" texture; this can be done either using WebGL drawing operations directly (using no extra canvas) or by uploading your 2D invisible canvas's contents to the texture (this is a built-in operation):

    var sourceTexture = gl.createTexture()
    gl.bindTexture(gl.TEXTURE_2D, sourceTexture)
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, sourceCanvas)
    // ...also set texture filters — see any WebGL tutorial...
    
  4. Render the other content to be multiplied to the "destination" texture.

  5. Finally, targeting the actual visible canvas, use a fragment shader to multiply the "source" and "destination" textures. The techniques here are those used for post-processing effects — I recommend looking up such a tutorial or simple example. Briefly, to apply a fragment shader to the entire canvas, you draw a full-screen quad - geometry that covers the entire viewport. The vertex shader is trivial, and the fragment shader would be like:

    varying vec2 texCoord;
    uniform sampler2D sourceTexture;
    uniform sampler2D destTexture;
    void main(void) {
      gl_FragColor = texture2D(sourceTexture, texCoord) * texture2D(destTexture, texCoord);
    }
    

If you want to do multiple overlapping multiply-blends per frame, then if there are no more than, say, 8, you can expand the above procedure to multiply several textures; if there are lots, you will need to do multiple stages of multiplying two textures while rendering to a third and then exchanging the roles.

If you would like a more specific answer, then please expand your question with more details on how many, and what kind of, graphics you are multiplying together.

Friday, September 17, 2021
 
millenomi
answered 1 Month ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :