Обсуждение: Checking data inserted during a transaction

Поиск
Список
Период
Сортировка

Checking data inserted during a transaction

От
Lynna Landstreet
Дата:
Hello all,

I'm working on an administrative interface in PHP for the art gallery
database I created last year, and running into a few issues.

Because information has to be entered into several different tables for each
exhibition, I've broken down the process of adding new exhibitions to the
databases into several pages, each of which processes the form data sent
from the previous page and then guides users through the next step (artists
featured in the exhibition, etc.).

I'm using transactions to handle this, so that at the end of the process the
user can (hopefully) review the data they've entered and either commit or
rollback the changes. But I'm having a bit of trouble figuring out whether
the data I'm trying to insert during the transaction is actually being
inserted.

From what I've read about transactions thus far, it looks to me as though
the data inserted should be visible in the database after the insert is done
but before the commit or rollback happens, and then disappear if rollback is
chosen. But that doesn't seem to be working.

I've loaded the data from the first form into an associative array, added
the name of the user who created and last modified the record (at this
stage, the same user) and the date created and last modified (again, the
same date, since this is the form for adding a new record), and printed the
array to make sure all the data is correct. Then I've used the following
statement to try and load it into the exhibitions table of the database:

$exh_query = pg_insert($db, 'exhibitions', $exh_info)
     or die ("Unable to insert data.");

$db is the database connection, and $exh_info is the array, which I've
already tested and made sure is working. Everything appears to go smoothly,
it doesn't die, no error message is generated - but the new row does not
show up in phpPgAdmin when I check there.

Have I done something wrong? Or am I confused and does data entered during a
transaction not actually show up until the commit? If that's the case, is
there any way I can display all the data for the user to review at the end
of the process before committing the changes? I was planning to pull it from
the database for that, but if it's not *in* the database, I can't do that.

And if I can't, is there perhaps some way to pass an array from one page to
the next for several pages, adding to it along the way? I know you can do
that with normal variables through either hidden form fields or putting them
in the URL, but I don't know about arrays... And at least one of the fields
(exhibition_description) is potentially several paragraphs long.

Any advice would be appreciated...

Thanks,

Lynna

P.S. My web host is running PHP 4.3.4 and PostgreSQL 7.4 if that's a factor.


--
Resource Centre Database Coordinator
Gallery 44
www.gallery44.org


Re: Checking data inserted during a transaction

От
"Chris"
Дата:
Hi Lynna,

You won't be able to see it in PHPPgAdmin until after it's committed.

The new data is only available to the current transaction. Once that
transaction is committed it becomes 'live'.


With PHP, when a script finishes, it will commit any unfinished
transactions (as far as I know) so a single transaction across multiple
pages won't work.


If you have shell access, you can see the transaction issue this way:

fire up 2 shell logins then in window 1

psql -d db
create table a(a int);

begin;
insert into a(a) values(1);
select * from a;

jump to shell 2
psql -d db
select * from a;
(will be empty)


jump back to shell 1
commit;

jump to shell 2 again
you will see 1 row.


You could serialize up the data in sessions and then use that data
before adding it to the database.
See http://www.php.net/serialize and http://www.php.net/unserialize and
http://www.php.net/session

Hope that helps a bit :)

Chris.


-----Original Message-----
From: pgsql-php-owner@postgresql.org
[mailto:pgsql-php-owner@postgresql.org] On Behalf Of Lynna Landstreet
Sent: Thursday, May 13, 2004 8:46 AM
To: pgsql-php@postgresql.org
Subject: [PHP] Checking data inserted during a transaction


Hello all,

I'm working on an administrative interface in PHP for the art gallery
database I created last year, and running into a few issues.

Because information has to be entered into several different tables for
each exhibition, I've broken down the process of adding new exhibitions
to the databases into several pages, each of which processes the form
data sent from the previous page and then guides users through the next
step (artists featured in the exhibition, etc.).

I'm using transactions to handle this, so that at the end of the process
the user can (hopefully) review the data they've entered and either
commit or rollback the changes. But I'm having a bit of trouble figuring
out whether the data I'm trying to insert during the transaction is
actually being inserted.

From what I've read about transactions thus far, it looks to me as
though the data inserted should be visible in the database after the
insert is done but before the commit or rollback happens, and then
disappear if rollback is chosen. But that doesn't seem to be working.

I've loaded the data from the first form into an associative array,
added the name of the user who created and last modified the record (at
this stage, the same user) and the date created and last modified
(again, the same date, since this is the form for adding a new record),
and printed the array to make sure all the data is correct. Then I've
used the following statement to try and load it into the exhibitions
table of the database:

$exh_query = pg_insert($db, 'exhibitions', $exh_info)
     or die ("Unable to insert data.");

$db is the database connection, and $exh_info is the array, which I've
already tested and made sure is working. Everything appears to go
smoothly, it doesn't die, no error message is generated - but the new
row does not show up in phpPgAdmin when I check there.

Have I done something wrong? Or am I confused and does data entered
during a transaction not actually show up until the commit? If that's
the case, is there any way I can display all the data for the user to
review at the end of the process before committing the changes? I was
planning to pull it from the database for that, but if it's not *in* the
database, I can't do that.

And if I can't, is there perhaps some way to pass an array from one page
to the next for several pages, adding to it along the way? I know you
can do that with normal variables through either hidden form fields or
putting them in the URL, but I don't know about arrays... And at least
one of the fields
(exhibition_description) is potentially several paragraphs long.

Any advice would be appreciated...

Thanks,

Lynna

P.S. My web host is running PHP 4.3.4 and PostgreSQL 7.4 if that's a
factor.


--
Resource Centre Database Coordinator
Gallery 44
www.gallery44.org


---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org


Re: Checking data inserted during a transaction

От
Joolz
Дата:
> [Lynna Landstreet schreef op 12-05-2004 18:45 -0400]

...

> From what I've read about transactions thus far, it looks to me as though
> the data inserted should be visible in the database after the insert is done

...

Have you checked if the visibility is only for the current db session?

--
07:16-07:17
Fedora Core release 1 (Yarrow) Linux 2.4.22-1.2188.nptl

Re: Checking data inserted during a transaction

От
Keary Suska
Дата:
on 5/12/04 4:45 PM, lynna@gallery44.org purportedly said:

> Because information has to be entered into several different tables for each
> exhibition, I've broken down the process of adding new exhibitions to the
> databases into several pages, each of which processes the form data sent
> from the previous page and then guides users through the next step (artists
> featured in the exhibition, etc.).
>
> I'm using transactions to handle this, so that at the end of the process the
> user can (hopefully) review the data they've entered and either commit or
> rollback the changes. But I'm having a bit of trouble figuring out whether
> the data I'm trying to insert during the transaction is actually being
> inserted.
>
> From what I've read about transactions thus far, it looks to me as though
> the data inserted should be visible in the database after the insert is done
> but before the commit or rollback happens, and then disappear if rollback is
> chosen. But that doesn't seem to be working.

As was mentioned, only the connection/process that "owns" the transaction
can see information altered within the transaction. In short, the answer to
your question is, "you can't."

You have a bigger issue, however. Because of the stateless nature of HTTP
and how PHP/Apache implements database connections, your multi-page process
will likely fail, as there is no guarantee that on any subsequent HTTP
requests that you will be using an existing connection/process (see also
first paragraph).

To use a multi-stage process, you will need to preserve the data yourself
(i.e. not insert into DB) at each step until the process is confirmed by the
end user. If the data is not too large you can preserve it within session
variables. Otherwise you may want to create a "safe" temp file, a reference
to which is maintained by the session.

Best regards,

Keary Suska
Esoteritech, Inc.
"Leveraging Open Source for a better Internet"


Re: Sessions and serializing (was: Checking data inserted

От
Lynna Landstreet
Дата:
Hmmm, so my entire idea for how to do this appears to have been unsound.
Well, better to find that out sooner than later! Thanks to everyone who
replied.

But I have a few questions:

on 5/12/04 7:36 PM, Chris at chris@interspire.com wrote:

> You could serialize up the data in sessions and then use that data
> before adding it to the database.
> See http://www.php.net/serialize and http://www.php.net/unserialize and
> http://www.php.net/session

OK, so if I understand this correctly, the serialize function can take
something like a big associative array containing all the data I want to be
able to write into the database and condense it into a single object that
can be passed via a hidden form field or something to that effect, correct?
Or the data can be put into the session array using $_SESSION, and then
passed by using a $session_id in the page URL?

But according to one of the user comments in the manual I have to use
addslashes() and stripslashes() if I want to be able to put the data into
the database after unserializing it - is that right?

Also, what about character encoding? My database and my web pages are utf-8
because of the presence of special characters in some of the artists and
names and image and exhibition titles (it's a Canadian gallery, so there are
a lot of French artists). Will serializing the array containing the data
affect that in any way?

Sorry if I'm being a pest - the whole session thing is new to me and I want
to make sure I understand it correctly.

Thanks,

Lynna

--
Resource Centre Database Coordinator
Gallery 44
www.gallery44.org


Re: Sessions and serializing (was: Checking data inserted

От
"Chris"
Дата:
Hi Lynna,

on 5/12/04 7:36 PM, Chris at chris@interspire.com wrote:

> You could serialize up the data in sessions and then use that data
> before adding it to the database. See http://www.php.net/serialize and

> http://www.php.net/unserialize and http://www.php.net/session

> OK, so if I understand this correctly, the serialize function can take
something like a big associative array containing all the data I want to
be able to write into the database and condense it into a single object
that can be passed via a hidden form field or something to that effect,
correct? Or the data can be put into the session array using $_SESSION,
and then passed by using a $session_id in the page URL?


You won't need to use unserialize and serialize per page if you're going
to use sessions - you only need those if you're going to pass the values
in a URL or in a hidden form field.

For sessions, you can simply
$my_array = array('1','2','3','4','5');
$_SESSION['blah'] = $my_array;

sort of thing..

> But according to one of the user comments in the manual I have to use
> addslashes() and stripslashes() if I want to be able to put the data
into the database after unserializing it - is that right?

Yep. So you'll need to do
$value = addslashes(serialize($real_value));

and use $value in your query...

Then when you fetch out

$real_value = unserialize(stripslashes($value));

Done =)

> Also, what about character encoding? My database and my web pages are
utf-8 because of the presence of special characters in some of the
artists and names and image and exhibition titles (it's a Canadian
gallery, so there are a lot of French artists). Will serializing the
array containing the data affect that in any way?

Not as far as I know, it should handle that fine.

> Sorry if I'm being a pest - the whole session thing is new to me and I
want to make sure I understand it correctly.

Ask as many questions as you need to, we've all been at the start before
=)


Re: Sessions and serializing (was: Checking data inserted

От
Lynna Landstreet
Дата:
on 5/19/04 10:46 PM, Chris at chris@interspire.com wrote:

> You won't need to use unserialize and serialize per page if you're going
> to use sessions - you only need those if you're going to pass the values
> in a URL or in a hidden form field.
>
> For sessions, you can simply
> $my_array = array('1','2','3','4','5');
> $_SESSION['blah'] = $my_array;
>
> sort of thing..

OK. So if I'm just saving things into the $_SESSION array, I don't need to
use serialize?

I've been reading through a whole bunch of session tutorials on DevShed,
PHPBuilder, etc. (although rather annoyingly nearly all of them are based on
PHP 4.0 and a lot of things seem to have changed with 4.2), and I think I'm
*starting* to get a grip on this, although some aspects are still a bit
confusing.

Most of the tutorials say that you can either pass session ids through the
URL or through cookies, and that using cookies is better for security
reasons. I'm OK with cookies because only a limited number of people will be
using the admin system I'm setting up and I can tell them they have to have
cookies enabled. It's not a part of the site that will be accessible to the
general public. And from the sounds of it the cookie is set automatically
without my having to do it with setcookie - right?

But the thing that's confusing me now is that apparently in 4.2,
--enable-trans-id is on by default, and that makes it automatically put the
session ID in the URLs of relative links, unless I've misunderstood what it
does? If passing the SID via URL is supposed to be bad from a security
standpoint, is there some way I can make it not do this? Bearing in mind
that I'm on a shared host so I can't mess with their overall PHP
configuration? Or am I worrying about this too much?



>> But according to one of the user comments in the manual I have to use
>> addslashes() and stripslashes() if I want to be able to put the data
> into the database after unserializing it - is that right?
>
> Yep. So you'll need to do
> $value = addslashes(serialize($real_value));
>
> and use $value in your query...
>
> Then when you fetch out
>
> $real_value = unserialize(stripslashes($value));
>
> Done =)

And that's only if I'm putting the session itself into a form field or
database, right?

If I extract the values from the $_SESSION array at the end of the update
process and insert them into the database then, having just used cookies to
store it in the meantime, then it doesn't need this? Or does it?


> Ask as many questions as you need to, we've all been at the start before
> =)

Thanks. Hopefully sooner or later I'll actually be at the point where I can
start answering other people's questions instead. :-)


Lynna

--
Resource Centre Database Coordinator
Gallery 44
www.gallery44.org


Re: Sessions and serializing (was: Checking data inserted

От
Lynna Landstreet
Дата:
Oh, and one more question I forgot. If session_start and/or adding variables
to $_SESSION does result in setting a cookie automatically, does that mean
it has to be done at the beginning of the script, before any output, like
with setcookie?


Lynna

--
Resource Centre Database Coordinator
Gallery 44
www.gallery44.org


Re: Sessions and serializing (was: Checking data inserted

От
"Chris"
Дата:
Hey Lynna,

> Oh, and one more question I forgot. If session_start and/or adding
variables to $_SESSION does result in setting a cookie automatically,
does that mean it has to be done at the beginning of the script, before
any output, like with setcookie?

Yes - you need to do a session_start() before any output gets sent. See
http://www.php.net/session_start for a bit more info about it..

>> You won't need to use unserialize and serialize per page if you're
>> going to use sessions - you only need those if you're going to pass
>> the values in a URL or in a hidden form field.
>>
>> For sessions, you can simply
>> $my_array = array('1','2','3','4','5');
>> $_SESSION['blah'] = $my_array;
>>
>> sort of thing..

>OK. So if I'm just saving things into the $_SESSION array, I don't need
to use serialize?

Correct.

>Most of the tutorials say that you can either pass session ids through
the URL or through cookies, and that using cookies is better for
security reasons. I'm OK with cookies because only a limited number of
people will be using the admin system I'm setting up and I can tell them
they have to have cookies enabled. It's not a part of the site that will
be accessible to the general public. And from the sounds of it the
cookie is set automatically without my having to do it with setcookie -
right?

Yep. Everything gets stored on the server in the session_save_path
directory (you can set this yourself in your scripts - see
http://www.php.net/session_save_path :)


>But the thing that's confusing me now is that apparently in 4.2,
--enable-trans-id is on by default, and that makes it automatically put
the session ID in the URLs of relative links, unless I've misunderstood
what it does? If passing the SID via URL is supposed to be bad from a
security standpoint, is there some way I can make it not do this?
Bearing in mind that I'm on a shared host so I can't mess with their
overall PHP configuration? Or am I worrying about this too much?

If it's a worry you can turn it off - http://www.php.net/ini_set - look
for session.use_trans_sid . Since it's a PHP_INI_SYSTEM|PHP_PER_DIR you
can change it in a .htaccess file ...


>>> But according to one of the user comments in the manual I have to
use
>>> addslashes() and stripslashes() if I want to be able to put the data
>> into the database after unserializing it - is that right?

>> Yep. So you'll need to do
>> $value = addslashes(serialize($real_value));
>> and use $value in your query...
>> Then when you fetch out
>> $real_value = unserialize(stripslashes($value));

>And that's only if I'm putting the session itself into a form field or
database, right?

Yep.

>If I extract the values from the $_SESSION array at the end of the
update process and insert them into the database then, having just used
cookies to store it in the meantime, then it doesn't need this? Or does
it?

It depends :)

eg dob could be stored as an array -
$dob = array('dd' => '01', 'mm' => '01', 'yy' => '1970');

then you'll need to serialize it before saving it..

If you want the values saved separately, then no you won't (eg q1 = 'y',
q2 = 'blah' etc etc).

HTH.

Chris.