php-general Digest 20 Sep 2008 12:26:18 -0000 Issue 5692
Topics (messages 280556 through 280564):
Re: Calculation assistance.. :)
280556 by: Stephen Johnson
Re: SESSIONS vs. MySQL
280557 by: Eric Butera
280558 by: Philip Thompson
280559 by: Jason Pruim
280560 by: Robert Cummings
280561 by: Stut
280562 by: Philip Thompson
280563 by: Stut
280564 by: Ashley Sheridan
Administrivia:
To subscribe to the digest, e-mail:
[EMAIL PROTECTED]
To unsubscribe from the digest, e-mail:
[EMAIL PROTECTED]
To post to the list, e-mail:
[EMAIL PROTECTED]
----------------------------------------------------------------------
--- Begin Message ---
Eric ... I LOVE YOU...
Thanks
--
Stephen Johnson c | eh
The Lone Coder
http://www.thelonecoder.com
continuing the struggle against bad code
http://www.fortheloveofgeeks.com
I¹m a geek and I¹m OK!
--
> From: Eric Gorr <[EMAIL PROTECTED]>
> Date: Fri, 19 Sep 2008 16:13:49 -0400
> To: Stephen Johnson <[EMAIL PROTECTED]>
> Cc: PHP list - not junk <[EMAIL PROTECTED]>
> Subject: Re: [PHP] Calculation assistance.. :)
>
> You originally had:
>
> $nPrincipal * ( $nMonthlyInterest / (1 - (1 + $nMonthlyInterest) ^ -
> $iMonths))
>
> which, translate to in PHP
>
> $nPrincipal * ( $nMonthlyInterest / (1 - pow( ( 1 +
> $nMonthlyInterest ), -$iMonths ) ) )
>
>
>
>
> On Sep 19, 2008, at 3:48 PM, Stephen Johnson wrote:
>
>> Right ... But that is producing even funkier results...
>>
>> doing pow( (1-(1+$nMonthlyInterest)) , ($iMonths*-1) ) ;
>>
>> Gives me :
>>
>> 4.2502451372964E-35 = 25000 * (0.0010416666666667 / 6.1270975733019E
>> +35);
>>
>>
>>> From: Eric Gorr <[EMAIL PROTECTED]>
>>>
>>> I believe what you are looking is:
>>>
>>> http://us2.php.net/manual/en/function.pow.php
>>>
>>> number pow ( number $base , number $exp )
>>> Returns base raised to the power of exp
>>>
>>>
>>>
>>> On Sep 19, 2008, at 3:34 PM, Stephen Johnson wrote:
>>>
>>>> OK.. Math is NOT my forte ...
>>>>
>>>> I am converting a site from ASP to PHP ... And this calc is in the
>>>> ASP Code
>>>> :
>>>>
>>>> $nMonthlyInterest = $nRate / (12 * 100)
>>>>
>>>> //' Calculate monthly payment
>>>> $nPayment = $nPrincipal * ( $nMonthlyInterest / (1 - (1 +
>>>> $nMonthlyInterest) ^ -$iMonths))
>>>>
>>>> Which then gives me in PHP
>>>> 0.0010416666666667 = 1.25 / (12 * 100);
>>>> -2.1701388888889 = 25000 * ( 0.0010416666666667 / (1 - (1 +
>>>> 0.0010416666666667) ^ -12)) ::
>>>>
>>>> ^ is the problem ...
>>>>
>>>> The solution SHOULD be 2,097.47 ... Not 2.17
>>>>
>>>> Would be willing to help correct this and make it valid in PHP?
>>>
>>
>>
>
--- End Message ---
--- Begin Message ---
On Fri, Sep 19, 2008 at 4:31 PM, Stut <[EMAIL PROTECTED]> wrote:
> On 19 Sep 2008, at 21:22, Robert Cummings wrote:
>>
>> On Fri, 2008-09-19 at 16:15 -0400, tedd wrote:
>>>
>>> At 3:11 PM -0400 9/19/08, Eric Butera wrote:
>>>>
>>>> On Fri, Sep 19, 2008 at 2:50 PM, Robert Cummings <[EMAIL PROTECTED]>
>>>> wrote:
>>>>>
>>>>> 4. lack of industry adoption
>>>>
>>>> There needs to be some sort of expensive test to certify one may wear
>>>> the badge. Then it will have higher adoption rates.
>>>
>>>
>>> I can modify this:
>>>
>>> http://webbytedd.com/bb/pdf/
>>
>> He said EXPENSIVE you insensitive clod!
>
> Ahh, mood swings from ink poisoning?
>
> Tedd: Charge $100 per certificate, Rob'll buy one, maybe even two!!
>
> I've managed to avoid getting the Zend certification until now despite many
> many people trying to convince me it's worth it. As both an employee and an
> employer I just don't see the value. The last practice tests I saw were
> primarily memory tests - that's not a useful measure in my book.
>
> -Stut
>
> --
> http://stut.net/
>
Bingo. :)
I can search php.net/<func> in 5 seconds to know the odd param order
of some string function if I forget.
--- End Message ---
--- Begin Message ---
I have more questions/responses throughout...
On Sep 19, 2008, at 1:12 PM, Stut wrote:
On 19 Sep 2008, at 18:47, Philip Thompson wrote:
I've narrowed it down to 10 initial queries...
1. Grab system config data (that's used in lots of places)
Does it change often? No? Then cache it in a PHP script. Use
var_export to create a file that you can include which will create
the configuration array. Alternatively cache it in a Memcache
instance which is where my system-wide config usually lives.
Good idea.
2. Grab session data (for SESSION array)
Meaning what? You say below that this is after the initial session
load. What are you loading here and why is it being loaded on every
page request if it's ending up in the $_SESSION array?
Because I'm using your class, Stut, (at least as a reference) to store
my sessions in the database. Hence, I have to pull them from the
database.
3. Grab page id
What does this do, how is it used, is it needed?
I was able to add this to the SESSION.
4. Grab user privs
IMHO you should only grab these when you need them.
I will need these on most pages anyway. Because of the architecture,
the security class (which uses these a lot) is a separate part.
5. Grab user session (for application)
Again, why isn't this already in $_SESSION for every page request
expect the first per visit?
This "user session" deals with merely keeping up with the time - how
long has it been since this user accessed the site? Keep logged in?
Logged in elsewhere? This uses the db and cookies. Note, this was
designed into the app from the beginning... using the _SESSION var is
new to the app as of this week. Yes, we can probably move this
functionality into the new _SESSION stuff....
6. Begin transaction
7. Lock user session row
8. Update user session
9. Commit transaction
If all you're doing is issuing an update command there is no need to
do so in a transaction and definitely no need to lock the row. An
update is atomic.
Maybe what you actually mean to do here is lock it before you get
the session data, make changes to it and then unlock it once you're
done changing it. Doing that would likely keep the row locked for
the entire duration of a request which can start causing problems as
traffic increases.
I'm starting the transaction because MySQL "SELECT... FOR UPDATE"
requires a transaction to lock the row. But now that I think about
it... the reason we use the lock is so that we don't have collisions
in data - specifically here the user session. However, the user
session row is only accessed by a single user (his/her own). And since
they can only be logged in at one location, there's virtually no way
for a collision. Right? I can remove queries 6, 7, and 9, right?
10. Add page tracking (an insert-only table that keeps track of
pages you visit)
I handle this using files and then have an offline processor to push
that data into the database. If all you're doing is adding a row to
the table you probably don't need this, but we do a fair amount of
work for each page view to record the data in a set of tables
designed for meaningful and speedy retrieval.
Note that these are the 10 queries that happen after the initial
SESSION load. I supposed I could reduce this by 1 or 2 queries - I
could store the page id/information in the session. Now with that
said, the queries are negligible (in elapsed time) and required.
However, I'm always open up to suggestions/improvements.... =D
You may think they're required, but I'm betting they're not if you
really think about it. However, if your DB can handle it then why
fix something that ain't broken.
It can handle it now. But I'm not worried about now. We have less than
10 clients/offices using the app. This may grow up to 100 within the
next year. That's when there's gonna be lots and lots of data and we
may start to see a slow down.
The way I approach this stuff is always with the knowledge that the
database is the most expensive resource in the infrastructure, so
anything I can do to avoid using it when it's not strictly necessary
is something I consider well-worth the effort.
With the rise of frameworks and the lazy architectures it's pretty
common to end up with this mass of DB access at the start of each
request, but it won't scale and it leads to assumptions that are
extremely expensive to find and fix when you do need to scale. Trust
me, I've been there many times and it's been painful every time!
Can you explain why it won't scale and may lead to assumptions?
Oh, and by scale I don't necessarily mean to tens of millions of
page views a month. Scalability is as much about going from 10
visitor a day to 1000 as it is from 1000 to several million.
-Stut
Thanks,
~Philip
--- End Message ---
--- Begin Message ---
Time's off by an hour :)
I could have my graphic designer whip something up hehee :)
On Sep 19, 2008, at 4:15 PM, tedd wrote:
At 3:11 PM -0400 9/19/08, Eric Butera wrote:
On Fri, Sep 19, 2008 at 2:50 PM, Robert Cummings <[EMAIL PROTECTED]
> wrote:
4. lack of industry adoption
There needs to be some sort of expensive test to certify one may wear
the badge. Then it will have higher adoption rates.
I can modify this:
http://webbytedd.com/bb/pdf/
Cheers,
tedd
--
-------
http://sperling.com http://ancientstones.com http://earthstones.com
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
--- End Message ---
--- Begin Message ---
On Fri, 2008-09-19 at 21:31 +0100, Stut wrote:
> >>
> >> I can modify this:
> >>
> >> http://webbytedd.com/bb/pdf/
> >
> > He said EXPENSIVE you insensitive clod!
>
> Ahh, mood swings from ink poisoning?
>
> Tedd: Charge $100 per certificate, Rob'll buy one, maybe even two!!
>
> I've managed to avoid getting the Zend certification until now despite
> many many people trying to convince me it's worth it. As both an
> employee and an employer I just don't see the value. The last practice
> tests I saw were primarily memory tests - that's not a useful measure
> in my book.
I'm also in the camp of avoiding getting Zend certification. As you
point out, it's merely a test on memorization of simple (and
occasionally obscure) language constructs. It's hardly an example of how
a person thinks, tackles problems, and can effectively develop
solutions.
Cheers,
Rob.
--
http://www.interjinn.com
Application and Templating Framework for PHP
--- End Message ---
--- Begin Message ---
On 19 Sep 2008, at 21:44, Philip Thompson wrote:
On Sep 19, 2008, at 1:12 PM, Stut wrote:
On 19 Sep 2008, at 18:47, Philip Thompson wrote:
4. Grab user privs
IMHO you should only grab these when you need them.
I will need these on most pages anyway. Because of the architecture,
the security class (which uses these a lot) is a separate part.
Fair enough, but I would suggest this is an ideal candidate for being
kept in the session.
5. Grab user session (for application)
Again, why isn't this already in $_SESSION for every page request
expect the first per visit?
This "user session" deals with merely keeping up with the time - how
long has it been since this user accessed the site? Keep logged in?
Logged in elsewhere? This uses the db and cookies. Note, this was
designed into the app from the beginning... using the _SESSION var
is new to the app as of this week. Yes, we can probably move this
functionality into the new _SESSION stuff....
Sounds like a lot of work for little benefit, but it sounds like it
might be hard to remove so I'd probably live with it for a while too.
6. Begin transaction
7. Lock user session row
8. Update user session
9. Commit transaction
If all you're doing is issuing an update command there is no need
to do so in a transaction and definitely no need to lock the row.
An update is atomic.
Maybe what you actually mean to do here is lock it before you get
the session data, make changes to it and then unlock it once you're
done changing it. Doing that would likely keep the row locked for
the entire duration of a request which can start causing problems
as traffic increases.
I'm starting the transaction because MySQL "SELECT... FOR UPDATE"
requires a transaction to lock the row. But now that I think about
it... the reason we use the lock is so that we don't have collisions
in data - specifically here the user session. However, the user
session row is only accessed by a single user (his/her own). And
since they can only be logged in at one location, there's virtually
no way for a collision. Right? I can remove queries 6, 7, and 9,
right?
Yes, you only need the update statement.
Note that these are the 10 queries that happen after the initial
SESSION load. I supposed I could reduce this by 1 or 2 queries - I
could store the page id/information in the session. Now with that
said, the queries are negligible (in elapsed time) and required.
However, I'm always open up to suggestions/improvements.... =D
You may think they're required, but I'm betting they're not if you
really think about it. However, if your DB can handle it then why
fix something that ain't broken.
It can handle it now. But I'm not worried about now. We have less
than 10 clients/offices using the app. This may grow up to 100
within the next year. That's when there's gonna be lots and lots of
data and we may start to see a slow down.
That's not even close to a large number of users, but it depends a lot
on what else the servers you're hosting it on are being used for.
The way I approach this stuff is always with the knowledge that the
database is the most expensive resource in the infrastructure, so
anything I can do to avoid using it when it's not strictly
necessary is something I consider well-worth the effort.
With the rise of frameworks and the lazy architectures it's pretty
common to end up with this mass of DB access at the start of each
request, but it won't scale and it leads to assumptions that are
extremely expensive to find and fix when you do need to scale.
Trust me, I've been there many times and it's been painful every
time!
Can you explain why it won't scale and may lead to assumptions?
Sure. With an architecture like this you start to assume that X is
available anywhere in your code because at the moment you know the
framework loads it for you. This makes it exceedingly difficult to
strip the initialisation code down if you end up needing to optimise
the crap out of it.
As far as scaling goes you're placing all the load on the database so
if you get to a stage where you can no longer vertically scale the DB
hardware you're left with a major rewrite of your entire codebase to
allow it to scale horizontally. It's possible that your app is capable
of being sharded across multiple servers but chances are that's still
going to take major surgery to achieve.
Some on the list may have noticed I'm a bit anal about scalability
issues, but it's only because I've inherited several systems now that
were never designed with scalability in mind and I ended up almost
completely rewriting each one. Every new site I develop now is built
so it's modular, can spread across multiple servers if/when needed and
doesn't waste resources. No doubt most web developers never hit these
problems, but I guess I've just been unlucky in that respect.
-Stut
--
http://stut.net/
--- End Message ---
--- Begin Message ---
On Sep 19, 2008, at 4:01 PM, Stut wrote:
On 19 Sep 2008, at 21:44, Philip Thompson wrote:
On Sep 19, 2008, at 1:12 PM, Stut wrote:
On 19 Sep 2008, at 18:47, Philip Thompson wrote:
4. Grab user privs
IMHO you should only grab these when you need them.
I will need these on most pages anyway. Because of the
architecture, the security class (which uses these a lot) is a
separate part.
Fair enough, but I would suggest this is an ideal candidate for
being kept in the session.
Yes, I agree - these can prob be moved into the session.
5. Grab user session (for application)
Again, why isn't this already in $_SESSION for every page request
expect the first per visit?
This "user session" deals with merely keeping up with the time -
how long has it been since this user accessed the site? Keep logged
in? Logged in elsewhere? This uses the db and cookies. Note, this
was designed into the app from the beginning... using the _SESSION
var is new to the app as of this week. Yes, we can probably move
this functionality into the new _SESSION stuff....
Sounds like a lot of work for little benefit, but it sounds like it
might be hard to remove so I'd probably live with it for a while too.
It may be some work... but it doesn't make sense to have session stuff
in two different places. (I inherited this architecture, so I've been
limited as to what I can do to some extent.) The question I have to
ask myself now... will it be worth it in the future to have moved the
session stuff to 1 class now? And do I have the time/resources to? =D
6. Begin transaction
7. Lock user session row
8. Update user session
9. Commit transaction
If all you're doing is issuing an update command there is no need
to do so in a transaction and definitely no need to lock the row.
An update is atomic.
Maybe what you actually mean to do here is lock it before you get
the session data, make changes to it and then unlock it once
you're done changing it. Doing that would likely keep the row
locked for the entire duration of a request which can start
causing problems as traffic increases.
I'm starting the transaction because MySQL "SELECT... FOR UPDATE"
requires a transaction to lock the row. But now that I think about
it... the reason we use the lock is so that we don't have
collisions in data - specifically here the user session. However,
the user session row is only accessed by a single user (his/her
own). And since they can only be logged in at one location, there's
virtually no way for a collision. Right? I can remove queries 6, 7,
and 9, right?
Yes, you only need the update statement.
Ok, here, only the update is needed. But for other locations where
multiple users may be accessing the same record, I should lock it.....
Note that these are the 10 queries that happen after the initial
SESSION load. I supposed I could reduce this by 1 or 2 queries -
I could store the page id/information in the session. Now with
that said, the queries are negligible (in elapsed time) and
required.
However, I'm always open up to suggestions/improvements.... =D
You may think they're required, but I'm betting they're not if you
really think about it. However, if your DB can handle it then why
fix something that ain't broken.
It can handle it now. But I'm not worried about now. We have less
than 10 clients/offices using the app. This may grow up to 100
within the next year. That's when there's gonna be lots and lots of
data and we may start to see a slow down.
That's not even close to a large number of users, but it depends a
lot on what else the servers you're hosting it on are being used for.
A client may have 1 user or 50 users. It's not the user-size I'm
concerned about. This software is for doctor's offices. So, last week
when we had our first import from another practice management system
(aptly acronym'd, PMS), our patient records jumped from about 1,000 to
65,000. That's just 1 client! Now, I still know that's not a whole
lot, but multiply that by 100 clients in the next year: 64000 * 100 =
6.4 million patient records. That's more of a significant number.
We're using a dedicated server that hosts the website and the
database. I *know* we're going to need to expand... but that's beyond
my control as a mere pawn. As of today, it's okay.
The way I approach this stuff is always with the knowledge that
the database is the most expensive resource in the infrastructure,
so anything I can do to avoid using it when it's not strictly
necessary is something I consider well-worth the effort.
With the rise of frameworks and the lazy architectures it's pretty
common to end up with this mass of DB access at the start of each
request, but it won't scale and it leads to assumptions that are
extremely expensive to find and fix when you do need to scale.
Trust me, I've been there many times and it's been painful every
time!
Can you explain why it won't scale and may lead to assumptions?
Sure. With an architecture like this you start to assume that X is
available anywhere in your code because at the moment you know the
framework loads it for you. This makes it exceedingly difficult to
strip the initialisation code down if you end up needing to optimise
the crap out of it.
As far as scaling goes you're placing all the load on the database
so if you get to a stage where you can no longer vertically scale
the DB hardware you're left with a major rewrite of your entire
codebase to allow it to scale horizontally. It's possible that your
app is capable of being sharded across multiple servers but chances
are that's still going to take major surgery to achieve.
Some on the list may have noticed I'm a bit anal about scalability
issues, but it's only because I've inherited several systems now
that were never designed with scalability in mind and I ended up
almost completely rewriting each one. Every new site I develop now
is built so it's modular, can spread across multiple servers if/when
needed and doesn't waste resources. No doubt most web developers
never hit these problems, but I guess I've just been unlucky in that
respect.
-Stut
Thanks for the explanation.
~Philip
--- End Message ---
--- Begin Message ---
On 19 Sep 2008, at 22:33, Philip Thompson wrote:
On Sep 19, 2008, at 4:01 PM, Stut wrote:
On 19 Sep 2008, at 21:44, Philip Thompson wrote:
On Sep 19, 2008, at 1:12 PM, Stut wrote:
On 19 Sep 2008, at 18:47, Philip Thompson wrote:
6. Begin transaction
7. Lock user session row
8. Update user session
9. Commit transaction
If all you're doing is issuing an update command there is no need
to do so in a transaction and definitely no need to lock the row.
An update is atomic.
Maybe what you actually mean to do here is lock it before you get
the session data, make changes to it and then unlock it once
you're done changing it. Doing that would likely keep the row
locked for the entire duration of a request which can start
causing problems as traffic increases.
I'm starting the transaction because MySQL "SELECT... FOR UPDATE"
requires a transaction to lock the row. But now that I think about
it... the reason we use the lock is so that we don't have
collisions in data - specifically here the user session. However,
the user session row is only accessed by a single user (his/her
own). And since they can only be logged in at one location,
there's virtually no way for a collision. Right? I can remove
queries 6, 7, and 9, right?
Yes, you only need the update statement.
Ok, here, only the update is needed. But for other locations where
multiple users may be accessing the same record, I should lock it.....
Yes and no. If all you're going to do while it's locked is issue the
update statement then it's pointless. However, if you need to prevent
anyone from updating the row from when you read it to when you write
it back then you need to lock it for the duration.
Note that these are the 10 queries that happen after the initial
SESSION load. I supposed I could reduce this by 1 or 2 queries -
I could store the page id/information in the session. Now with
that said, the queries are negligible (in elapsed time) and
required.
However, I'm always open up to suggestions/improvements.... =D
You may think they're required, but I'm betting they're not if
you really think about it. However, if your DB can handle it then
why fix something that ain't broken.
It can handle it now. But I'm not worried about now. We have less
than 10 clients/offices using the app. This may grow up to 100
within the next year. That's when there's gonna be lots and lots
of data and we may start to see a slow down.
That's not even close to a large number of users, but it depends a
lot on what else the servers you're hosting it on are being used for.
A client may have 1 user or 50 users. It's not the user-size I'm
concerned about. This software is for doctor's offices. So, last
week when we had our first import from another practice management
system (aptly acronym'd, PMS), our patient records jumped from about
1,000 to 65,000. That's just 1 client! Now, I still know that's not
a whole lot, but multiply that by 100 clients in the next year:
64000 * 100 = 6.4 million patient records. That's more of a
significant number.
Not particularly, and to be honest the traffic to the site will be
your problem, not the number of users or records stored on it. Queries
can always be optimised but the architecture of the site is harder and
more expensive to change.
We're using a dedicated server that hosts the website and the
database. I *know* we're going to need to expand... but that's
beyond my control as a mere pawn. As of today, it's okay.
Sounds like you've got an easy sharding option so you should be ok.
Once you outgrow that single server it should be pretty simple to put
a redirector on to a main server which will redirect after login to
another server (shard) which contains all the data for that client.
This is commonly the easiest sharding scenario to implement but it
only works so long as a single client doesn't outgrow a single server.
-Stut
--
http://stut.net/
--- End Message ---
--- Begin Message ---
On Fri, 2008-09-19 at 10:17 -0500, Philip Thompson wrote:
> Hi all.
>
> Let me start out by saying, I have STFW and read through the list
> archives. Now that that's out of the way.
>
> To speed up our application, we want to implement using SESSIONs in
> some locations. Beforehand, on every page, we would run approximately
> 30-40 queries just to get the page setup - user information and other
> stuff. Now while we can't take away all of the setup queries, we would
> like to reduce the startup number.
>
> Ok, so I've implemented this in several places where information
> basically does not change from page to page. Jumping to the point/
> question... when does it become more inefficient to store lots of
> information in SESSION variables than to run several more queries?
> Note, we are actually storing sessions in the database - so a read/
> write is required on each page load - it's not file sessions.
>
> Now I know this can depend on the complexity of the queries and how
> much data is actually stored inside the sessions... but initial
> thoughts? To give you a number, the strlen of the _SESSION array is
> 325463 - which is equivalent to the number of bytes (I think).
>
> Thanks,
> ~Philip
>
Why do you have so many queries? Is there any way you could use joins to
drop that number down. It might not seem like lot when only a few
people are using the site, but it will start being a problem when you
get more people using it.
Ash
www.ashleysheridan.co.uk
--- End Message ---