Asked  7 Months ago    Answers:  5   Viewed   49 times

I'm trying to write an iterator for results from a PDO statement but I can't find any way of rewinding to the first row. I would like to avoid the overhead of calling fetchAll and storing all the result data.

// first loop works fine
foreach($statement as $result) {
    // do something with result
}

// but subsequent loops don't
foreach($statement as $result) {
    // never called 
}

Is there some way of reseting the statement or seeking the first row?

 Answers

69

I'm pretty sure this is database dependent. Because of that, it is something you should try to avoid. However, I think you can achieve what you want by enabling buffered queries. If that doesn't work, you can always pull the result into an array with fetchAll. Both solutions have implications for your applications performance, so think twice about it, if the resultsets are large.

Wednesday, March 31, 2021
 
juananrey
answered 7 Months ago
73

showdev's comment is correct that the PDO DSN does not allow host:port syntax.

If your CMS is defining DB_HOST outside of your control, you can't use that constant directly. But you can pull information out of it.

$host_port = preg_replace('/:(d+)/', ';port=${1}', DB_HOST);
$db = new PDO("mysql:host={$host_port};dbname=".DB_NAME.";charset=utf8", 
    DB_USER, DB_PW, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
Friday, May 28, 2021
 
Chvanikoff
answered 5 Months ago
20

Just put the result of fetch into a variable:

if($row = $q->fetch()) {
    // $row contains first fetched row
    echo $row['coloumn_name'];
}
else
    // no results
Saturday, May 29, 2021
 
barden
answered 5 Months ago
59

As I know, PDO_MYSQLND replaced PDO_MYSQL in PHP 5.3. Confusing part is that name is still PDO_MYSQL. So now ND is default driver for MySQL+PDO.

Overall, to execute multiple queries at once you need:

  • PHP 5.3+
  • mysqlnd
  • Emulated prepared statements. Make sure PDO::ATTR_EMULATE_PREPARES is set to 1 (default). Alternatively you can avoid using prepared statements and use $pdo->exec directly.

Using exec

$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');

// works regardless of statements emulation
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);

$sql = "
DELETE FROM car; 
INSERT INTO car(name, type) VALUES ('car1', 'coupe'); 
INSERT INTO car(name, type) VALUES ('car2', 'coupe');
";

$db->exec($sql);

Using statements

$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');

// works not with the following set to 0. You can comment this line as 1 is default
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);

$sql = "
DELETE FROM car; 
INSERT INTO car(name, type) VALUES ('car1', 'coupe'); 
INSERT INTO car(name, type) VALUES ('car2', 'coupe');
";

$stmt = $db->prepare($sql);
$stmt->execute();

A note:

When using emulated prepared statements, make sure you have set proper encoding (that reflects actual data encoding) in DSN (available since 5.3.6). Otherwise there can be a slight possibility for SQL injection if some odd encoding is used.

Tuesday, June 1, 2021
 
anjan
answered 5 Months ago
30

You need to configure extensions list inside chromeOptions:

capabilities {
    'browserName': 'chrome',
    'chromeOptions': {
        'extensions': ['base64 encoded extension']
    }
}

Note that it in extensions, it is important to provide a list of base-64 encoded packed Chrome extension.

To get a base64 encoded extension, you need to read the .ctx extension file and encode the contents with base64. For example, using python:

>>> import base64
>>> data = open('path_to_the_ctx_extension').read()
>>> base64.standard_b64encode(data).decode('UTF-8')
# outputs the encoded chrome extension which you can paste in the config

Or, easier, make a helper.js file using fs and q:

var q = require('q');
var fs = require('fs');

exports.getCapabilities = function (filename) {
    var deferred = q.defer();

    fs.readFile(filename, function (err, data) {
        var capabilities = {
            'browserName': 'chrome',
            'chromeOptions': {
                extensions: [
                    data.toString('base64')
                ]
            }
        };
        deferred.resolve(capabilities);
    });

    return deferred.promise;
};

Then, in your protractor config, use this getCapabilities() function to get capabilities:

var helper = require('./helper.js');

exports.config = {

    capabilities: helper.getCapabilities('/path/to/crx/extension'),

    ...
}

Currently, it works with a single extension, so there is a room for improvement.

Also, look through the following issue in case you have problems:

  • Setting Chrome Options
Tuesday, July 20, 2021
 
muaddhib
answered 3 Months 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 :
 
Share