1

I'm trying to write data from a simple form to an SQLite database, but even though I'm committing the transactions, nothing is written to the database file. This is the php code:

$expense = new Model();
$expense->add_expense($_POST);

and in the Model class:

class Model {

    private $database = 'expenses.db';
    private $dbh;

    function __construct() {
        $this->dbh = new PDO('sqlite:/var/www/expenses/' . $this->database);
        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }

    public function add_expense($args) {
        $stmt = $this->dbh->prepare('INSERT INTO `expenses` (`type`, `name`, `location`, `receipt_date`, `price`, `notes`) VALUES (?, ?, ?, ?, ?, ?)');
        $this->dbh->beginTransaction();
        $stmt->execute(array_values($args));
        $this->dbh->commit();     
    }
}

This is the contents of $args, from inside the function:

Array
(
    [type] => type
    [name] => item_name
    [location] => place
    [date] => 1313180040
    [price] => 8.86
    [notes] => none
)

Also, $stmt->getMessage(); doesn't output anything. This is the SQL to create the table:

BEGIN TRANSACTION;
CREATE TABLE expenses (notes TEXT, type TEXT, location TEXT, name TEXT, price NUMERIC, receipt_date NUMERIC);
COMMIT;

Validation isn't relevant, so I left it out. The contents of $args that I listed is after validation occurs, and it's all correct.

UPDATE: Same code but using bindParam and named parameters instead:

$stmt = $this->dbh->prepare('INSERT INTO `expenses` (`type`, `name`, `location`, `receipt_date`, `price`, `notes`) VALUES (:type, :name, :location, :receipt_date, :price, :notes)');

and the binding statements:

$stmt->bindParam(':type', $args['type']);
$stmt->bindParam(':name', $args['name']);
$stmt->bindParam(':location', $args['location']);
$stmt->bindParam(':receipt_date', $args['date']);
$stmt->bindParam(':price', $args['price']);
$stmt->bindParam(':notes', $args['notes']);
$stmt->execute();

Still, nothing happens.

6
  • 1
    Try adding the following to the constructor: $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);. This makes PDO throw exceptions when an error occurs (instead of ignoring it silently as it does by default). It might tell you what's wrong. I have never used transactions in PDO myself. Commented Aug 19, 2011 at 18:35
  • I normally use that in my Model constructors, but I completely forgot it this time. No exception is thrown, though. I don't know if it's related, but when I try to open the database with sqlite expenses.db (when I'm /var/www/expenses) I get an error message of Unable to open database "expenses.db": file is encrypted or is not a database Commented Aug 19, 2011 at 18:37
  • 1
    What happens when you bind the parameters individually with $stmt->bindParam()? I don't know if it's significant but all examples that I found online use PDO::exec() rather than PDOStatement::execute() with beginTransaction() and commit(). Commented Aug 19, 2011 at 19:15
  • I haven't found anything that says prepared statements and execute can't be used within a transaction, but even when I remove the two lines of transactional code, nothing happens. I added code with binding named parameters, too, if that helps. I fixed the problem of opening the db from the command line: I was using sqlite instead of sqlite3. I recreated the database using the sqlite3 command and recreated the table, but nothing happens. Commented Aug 19, 2011 at 19:19
  • 1
    I'm afraid I'm out of ideas. I ran your original code on Windows with the following array as $_POST: array('type' => 'type', 'name' => 'name', 'location' => 'place', 'receipt_date' => 12345, 'price' => 15.00, 'notes' => 'none') and the record was inserted. Commented Aug 19, 2011 at 19:33

2 Answers 2

1

Solved it; The command sqlite3 expenses.db created the database with my linux user account as the owner, but the php script runs through the web server, so the owner is www-data. I changed the ownership and permissions, and it's working fine now. Thank you for the help!

Sign up to request clarification or add additional context in comments.

Comments

0

but even the command line sqlite3 has problems with owner script to owner db writes: viz: sqlite> INSERT INTO author (name) VALUES ('Hugh MacDairmid'); only after opening the terminal with su ( or using sudo ) did the db writes occur. I suppose this should not be a surprise.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.