php-general Digest 20 Jan 2011 03:45:38 -0000 Issue 7142
Topics (messages 310869 through 310889):
Re: switch case madness
310869 by: Daniel Brown
310870 by: Joshua Kehn
310872 by: David Hutto
310881 by: Micky Hulse
310882 by: Joshua Kehn
310883 by: Adam Richardson
310884 by: Richard Sharp
Re: Delivery Status Notification (Failure)
310871 by: Daniel Brown
Re: Autorename extracted files from zip-archive
310873 by: Richard Quadling
Re: Class and interface location
310874 by: Adam Richardson
310876 by: larry.garfieldtech.com
310877 by: Richard Quadling
310878 by: Adam Richardson
310879 by: larry.garfieldtech.com
310880 by: larry.garfieldtech.com
310885 by: David Harkness
310886 by: larry.garfieldtech.com
310887 by: Peter Lind
310888 by: Tommy Pham
310889 by: larry.garfieldtech.com
News Server Time Outs
310875 by: Al
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 ---
On Tue, Jan 18, 2011 at 23:39, Joshua Kehn <[email protected]> wrote:
>
> Why not use one of the countless, not to mention secure and stable cookie
> management systems available? If it's an exercise cool, I misunderstood.
>
> I'm not one to normally shun people rolling their own code, lord knows I've
> done it more then once or twice, but there are some things I wouldn't touch
> with a ten foot pool, and cookie management is one of them. The other would
> be things like CSV parsers or text manipulations.
The use of existing packages is so increasingly prevalent that I
have the unfortunate displeasure of knowing many "developers" who do
nothing but this, yet who can't even answer simple questions about
general coding, and who cry and complain that a "previous developer"
must have borked something. I think Donovan is right on track here
--- he's just getting started, and challenging himself to learn the
language at a deeper level. That will make him a developer, not just
a copy-and-paster.
I do see from where it is you're coming, though, Josh --- once
you've gotten the fundamentals, a lot of times it's easier - sometimes
even a better idea - to use an existing, mature solution. What helps
you to determine its value from a code standpoint? Your existing
experience.
--
</Daniel P. Brown>
Network Infrastructure Manager
Documentation, Webmaster Teams
http://www.php.net/
--- End Message ---
--- Begin Message ---
> On Tue, Jan 18, 2011 at 23:39, Joshua Kehn <[email protected]> wrote:
> The use of existing packages is so increasingly prevalent that I
> have the unfortunate displeasure of knowing many "developers" who do
> nothing but this, yet who can't even answer simple questions about
> general coding, and who cry and complain that a "previous developer"
> must have borked something. I think Donovan is right on track here
> --- he's just getting started, and challenging himself to learn the
> language at a deeper level. That will make him a developer, not just
> a copy-and-paster.
>
> I do see from where it is you're coming, though, Josh --- once
> you've gotten the fundamentals, a lot of times it's easier - sometimes
> even a better idea - to use an existing, mature solution. What helps
> you to determine its value from a code standpoint? Your existing
> experience.
>
> --
> </Daniel P. Brown>
> Network Infrastructure Manager
> Documentation, Webmaster Teams
> http://www.php.net/
You are correct, and it is a shame to see many developers fall into the copy /
paste realm, especially with a language like PHP where such snippets are often
found easily but of dubious quality. Rolling your own is a great way to
understand how things work (or should work) internally, as well as giving you
valuable practice. I don't mean to discredit is. As I mentioned, more often
then not I'm a fan of it.
Regards,
-Josh
____________________________________
Joshua Kehn | [email protected]
http://joshuakehn.com
--- End Message ---
--- Begin Message ---
.
>>
>> I do see from where it is you're coming, though, Josh --- once
>> you've gotten the fundamentals, a lot of times it's easier - sometimes
>> even a better idea - to use an existing, mature solution. What helps
>> you to determine its value from a code standpoint? Your existing
>> experience.
>>
>> --
>> </Daniel P. Brown>
>> Network Infrastructure Manager
>> Documentation, Webmaster Teams
>> http://www.php.net/
>
> You are correct, and it is a shame to see many developers fall into the copy
> / paste realm, especially with a language like PHP where such snippets are
> often found easily but of dubious quality. Rolling your own is a great way to
> understand how things work (or should work) internally, as well as giving you
> valuable practice. I don't mean to discredit is. As I mentioned, more often
> then not I'm a fan of it.
>
> Regards,
>
> -Josh
> ____________________________________
> Joshua Kehn | [email protected]
> http://joshuakehn.com
>
>
I find that at first, in any language, playing with the snippets
through a form of stimuli and response(I move this, this happens, or
doesn;t), helps to reinforce what I'm learning.
But after understanding the snippet, I don't find that reapplying it
later subverts the concept of being a 'real coder', because in the end
you want to move to a more efficient means of coding, which is, if I'm
not mistaken, where these larger frameworks come from-snippets that
are reusable(all the way down to a login system snippet).
--
It sure does get lonely up under this bridge.
--- End Message ---
--- Begin Message ---
On Wed, Jan 19, 2011 at 6:45 AM, Joshua Kehn <[email protected]> wrote:
> On Jan 19, 2011, at 9:43 AM, Jay Blanchard wrote:
>> [snip]
>> ...
>> [/snip]
>> Imagine when there'll be the day when you do not have to code at
>> all...just copy 'n paste snippets together in the order that you wish
>> them to work in and Voila'! - instant web app.
>> Thpppppppppppptttttttttttttttt!!!!!!
> They have that. It's called Ruby on Rails.
CodeIgniter and/or Django (Python) are fun.
What about a middle of the road solution?
Google for "php micro framework" and/or "python micro framework".
I have yet to use a micro framework myself, but I am looking forward
to playing around with one for one of my next PHP projects... I would
love to find one that has a decent "micro" templating system. :D
M
--- End Message ---
--- Begin Message ---
On Jan 19, 2011, at 12:44 PM, Micky Hulse wrote:
> On Wed, Jan 19, 2011 at 6:45 AM, Joshua Kehn <[email protected]> wrote:
>> They have that. It's called Ruby on Rails.
>
> CodeIgniter and/or Django (Python) are fun.
>
> What about a middle of the road solution?
>
> Google for "php micro framework" and/or "python micro framework".
>
> I have yet to use a micro framework myself, but I am looking forward
> to playing around with one for one of my next PHP projects... I would
> love to find one that has a decent "micro" templating system. :D
>
> M
I love using CodeIgniter. I think it's the best minimalist PHP framework out
there, and thankfully it doesn't pretend to be Rails.
I've been told to look at Lithium but haven't gotten around to it yet.
Regards,
-Josh
____________________________________
Joshua Kehn | [email protected]
http://joshuakehn.com
--- End Message ---
--- Begin Message ---
On Wed, Jan 19, 2011 at 12:44 PM, Micky Hulse <[email protected]>wrote:
> On Wed, Jan 19, 2011 at 6:45 AM, Joshua Kehn <[email protected]> wrote:
> > On Jan 19, 2011, at 9:43 AM, Jay Blanchard wrote:
> >> [snip]
> >> ...
> >> [/snip]
> >> Imagine when there'll be the day when you do not have to code at
> >> all...just copy 'n paste snippets together in the order that you wish
> >> them to work in and Voila'! - instant web app.
> >> Thpppppppppppptttttttttttttttt!!!!!!
> > They have that. It's called Ruby on Rails.
>
> CodeIgniter and/or Django (Python) are fun.
>
> What about a middle of the road solution?
>
> Google for "php micro framework" and/or "python micro framework".
>
> I have yet to use a micro framework myself, but I am looking forward
> to playing around with one for one of my next PHP projects... I would
> love to find one that has a decent "micro" templating system. :D
>
> M
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
Here are some interesting frameworks you might want to check out:
Lithium
Fat-free
Limonade
Nephtali (my framework) fits within one file (except the config file).
I'll send you a note off-list highlighting Nephtali's features.
Adam
--
Nephtali: A simple, flexible, fast, and security-focused PHP framework
http://nephtaliproject.com
--- End Message ---
--- Begin Message ---
LOL, so true
-----Original Message-----
From: Adam Richardson [mailto:[email protected]]
Sent: Wednesday, January 19, 2011 12:28 PM
To: PHP-General
Subject: Re: [PHP] switch case madness
On Wed, Jan 19, 2011 at 12:44 PM, Micky Hulse
<[email protected]>wrote:
> On Wed, Jan 19, 2011 at 6:45 AM, Joshua Kehn <[email protected]>
wrote:
> > On Jan 19, 2011, at 9:43 AM, Jay Blanchard wrote:
> >> [snip]
> >> ...
> >> [/snip]
> >> Imagine when there'll be the day when you do not have to code at
> >> all...just copy 'n paste snippets together in the order that you
wish
> >> them to work in and Voila'! - instant web app.
> >> Thpppppppppppptttttttttttttttt!!!!!!
> > They have that. It's called Ruby on Rails.
>
> CodeIgniter and/or Django (Python) are fun.
>
> What about a middle of the road solution?
>
> Google for "php micro framework" and/or "python micro framework".
>
> I have yet to use a micro framework myself, but I am looking forward
> to playing around with one for one of my next PHP projects... I would
> love to find one that has a decent "micro" templating system. :D
>
> M
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
Here are some interesting frameworks you might want to check out:
Lithium
Fat-free
Limonade
Nephtali (my framework) fits within one file (except the config file).
I'll send you a note off-list highlighting Nephtali's features.
Adam
--
Nephtali: A simple, flexible, fast, and security-focused PHP framework
http://nephtaliproject.com
--- End Message ---
--- Begin Message ---
On Wed, Jan 19, 2011 at 10:28, Mail Delivery Subsystem
<[email protected]> wrote:
> Delivery to the following recipient failed permanently:
>
> [email protected]
>
> Technical details of permanent failure:
> Google tried to deliver your message, but it was rejected by the recipient
> domain. We recommend contacting the other email provider for further
> information about the cause of this error. The error that the other server
> returned was: 552 552 5.7.1 <[email protected]>: Recipient address
> rejected: User has been over quota for > 1 week, email rejected (state 14).
Hey, Merlin, delete some of your pr0n, SPAM, and Farmville invites
before you send emails to the list next time, please. ;-P
--
</Daniel P. Brown>
Network Infrastructure Manager
Documentation, Webmaster Teams
http://www.php.net/
--- End Message ---
--- Begin Message ---
On 19 January 2011 14:06, Merlin Morgenstern <[email protected]> wrote:
> Hello,
>
> I am using shell_exec to uncompress zip files which works fine, but has one
> big problem. Whenever the zip-archive containes an already existing file
> name, it will overwrite the current one. I need the file to be extracted and
> autorenamed.
>
> This is the code line:
>
> $output = shell_exec('unzip -jo '.$filename.' -d '.$path);
>
> Does anybody know a way on how to autorename existing files?
>
> I thought about a workaround on extracting to a tmp folder and then moving
> to the proper directory while renaming the files if they already exists.
> Unfortunatelly I could not find a way to do this.
>
> Thank you for any help on this.
>
> Merlin
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
As you are using an external app (unzip), does it support any sort of
renaming? PHP isn't actually involved in the extraction process in
this instance.
You may be better off using the ZIP extension in PHP to extract the
data and write it to your own files.
--
Richard Quadling
Twitter : EE : Zend
@RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
--- End Message ---
--- Begin Message ---
On Wed, Jan 19, 2011 at 8:21 AM, Richard Quadling <[email protected]>wrote:
> On 19 January 2011 07:46, Adam Richardson <[email protected]> wrote:
> > On Wed, Jan 19, 2011 at 2:07 AM, Larry Garfield <[email protected]
> >wrote:
> >
> >> 3) Static analysis. Instead of reflection, either tokenize or string
> parse
> >> all files to determine what classes implement what interfaces and then
> >> cache
> >> that information. We are actually using this method now to locate
> classes,
> >> and it works surprisingly well. Because we never parse code into memory
> it
> >> does not ever spike the memory usage. However, it is impossible to
> >> determine
> >> if a class implements a given interface by static analysis unless it
> >> declare
> >> so itself with the implements keyword. If it does so indirectly via
> >> inheritance, either via the class or via the interface, it would not
> find
> >> it.
> >> That necessitates that any "detectable" classes must explicitly
> themselves
> >> declare their interfaces, even if it is redundant to do so. I don't
> like
> >> that
> >> approach, but it's the first one that strikes me as even viable.
> >>
> >
> > 4) Explicit declaration. In this approach we detect nothing and rely on
> the
> >> plugin developer to do everything. That is, they must provide somewhere
> >> (either in code or a configuration file) an index of all classes they
> >> offer,
> >> the interfaces they implement, and the file in which they live. While
> this
> >> makes the implementation easy, it is a huge burden on the plugin
> developer
> >> and
> >> I'm quite sure they'll forget to do so or get it wrong on a regular
> basis.
> >>
> >
> > I'd suggest combining 3 and 4. Build a tool that performs a static
> analysis
> > of a group of files and make it easy for developers to use. This tool
> would
> > generate the explicit declarations your codebase would utilize when
> > answering such questions as "which classes implement interface foo". The
> > file the static analysis tool generates could be easily hand editable, so
> > developers could tweak it if they see issues (just in case the static
> > analysis tool has bugs early on), or for small plugins, just quick crank
> out
> > a couple lines by hand.
> >
> > As long as the static analysis tool builds a composite of class hierarchy
> > established in all the files (project wide, at least in terms of the
> > plugin), you wouldn't have to double declare interfaces so they could be
> > detected.
> >
> > Adam
> >
> > --
> > Nephtali: A simple, flexible, fast, and security-focused PHP framework
> > http://nephtaliproject.com
> >
>
> There is a pecl extension called inclued [1] & [2] which could be used I
> think.
>
> It can be used to produce a list of all the relationships between
> included files, so a one off pass of all the class files (simply
> include them) and then retrieve the analysis from inclued.
>
> You can now build a class dependency tree from that data and cache it.
>
> Pretty much exactly what you need.
>
Richard,
While inclued performs a nice analysis of the files included at a given
stage of a script, I don't see that it performs a static analysis of the PHP
contained within the files so Larry could use it to detect the interfaces
implemented in a given set of PHP files.
I looked at the pages:
http://docs.php.net/manual/en/inclued.examples-implementation.php
http://docs.php.net/manual/en/function.inclued-get-data.php
I'm curious about this feature myself, so if I missed something, please let
me know.
Thanks,
Adam
--
Nephtali: A simple, flexible, fast, and security-focused PHP framework
http://nephtaliproject.com
--- End Message ---
--- Begin Message ---
On 1/19/11 10:09 AM, Adam Richardson wrote:
On Wed, Jan 19, 2011 at 8:21 AM, Richard Quadling<[email protected]>wrote:
On 19 January 2011 07:46, Adam Richardson<[email protected]> wrote:
On Wed, Jan 19, 2011 at 2:07 AM, Larry Garfield<[email protected]
wrote:
3) Static analysis. Instead of reflection, either tokenize or string
parse
all files to determine what classes implement what interfaces and then
cache
that information. We are actually using this method now to locate
classes,
and it works surprisingly well. Because we never parse code into memory
it
does not ever spike the memory usage. However, it is impossible to
determine
if a class implements a given interface by static analysis unless it
declare
so itself with the implements keyword. If it does so indirectly via
inheritance, either via the class or via the interface, it would not
find
it.
That necessitates that any "detectable" classes must explicitly
themselves
declare their interfaces, even if it is redundant to do so. I don't
like
that
approach, but it's the first one that strikes me as even viable.
4) Explicit declaration. In this approach we detect nothing and rely on
the
plugin developer to do everything. That is, they must provide somewhere
(either in code or a configuration file) an index of all classes they
offer,
the interfaces they implement, and the file in which they live. While
this
makes the implementation easy, it is a huge burden on the plugin
developer
and
I'm quite sure they'll forget to do so or get it wrong on a regular
basis.
I'd suggest combining 3 and 4. Build a tool that performs a static
analysis
of a group of files and make it easy for developers to use. This tool
would
generate the explicit declarations your codebase would utilize when
answering such questions as "which classes implement interface foo". The
file the static analysis tool generates could be easily hand editable, so
developers could tweak it if they see issues (just in case the static
analysis tool has bugs early on), or for small plugins, just quick crank
out
a couple lines by hand.
As long as the static analysis tool builds a composite of class hierarchy
established in all the files (project wide, at least in terms of the
plugin), you wouldn't have to double declare interfaces so they could be
detected.
Adam
That is essentially #3. The static analysis results could easily be
cached in a human-editable form, but in practice I don't think that will
be viable. The humans who will be running this system will largely be
non-PHP-gurus so asking them to validate the accuracy of a giant PHP
array dumped to a file is going to be a losing battle. If we're
actually building a full graph to determine indirect implementation that
would then preclude pre-deriving information per-plugin and just
shipping a manifest file with each plugin. (I could be convinced of
that as an approach, but that still doesn't solve the indirect
implementation problem.)
There is a pecl extension called inclued [1]& [2] which could be used I
think.
It can be used to produce a list of all the relationships between
included files, so a one off pass of all the class files (simply
include them) and then retrieve the analysis from inclued.
You can now build a class dependency tree from that data and cache it.
Pretty much exactly what you need.
Richard,
While inclued performs a nice analysis of the files included at a given
stage of a script, I don't see that it performs a static analysis of the PHP
contained within the files so Larry could use it to detect the interfaces
implemented in a given set of PHP files.
I looked at the pages:
http://docs.php.net/manual/en/inclued.examples-implementation.php
http://docs.php.net/manual/en/function.inclued-get-data.php
I'm curious about this feature myself, so if I missed something, please let
me know.
Thanks,
Adam
Yeah, inclued looks cool but it looks like a runtime analysis tool, not
a static analysis tool. That runs into the same problem as reflection
where I'd have to include the whole code base in order to build up the
indexes I need.
--Larry Garfield
--- End Message ---
--- Begin Message ---
On 19 January 2011 16:23, [email protected] <[email protected]> wrote:
> On 1/19/11 10:09 AM, Adam Richardson wrote:
>>
>> On Wed, Jan 19, 2011 at 8:21 AM, Richard
>> Quadling<[email protected]>wrote:
>>
>>> On 19 January 2011 07:46, Adam Richardson<[email protected]> wrote:
>>>>
>>>> On Wed, Jan 19, 2011 at 2:07 AM, Larry Garfield<[email protected]
>>>> wrote:
>>>>
>>>>> 3) Static analysis. Instead of reflection, either tokenize or string
>>>
>>> parse
>>>>>
>>>>> all files to determine what classes implement what interfaces and then
>>>>> cache
>>>>> that information. We are actually using this method now to locate
>>>
>>> classes,
>>>>>
>>>>> and it works surprisingly well. Because we never parse code into
>>>>> memory
>>>
>>> it
>>>>>
>>>>> does not ever spike the memory usage. However, it is impossible to
>>>>> determine
>>>>> if a class implements a given interface by static analysis unless it
>>>>> declare
>>>>> so itself with the implements keyword. If it does so indirectly via
>>>>> inheritance, either via the class or via the interface, it would not
>>>
>>> find
>>>>>
>>>>> it.
>>>>> That necessitates that any "detectable" classes must explicitly
>>>
>>> themselves
>>>>>
>>>>> declare their interfaces, even if it is redundant to do so. I don't
>>>
>>> like
>>>>>
>>>>> that
>>>>> approach, but it's the first one that strikes me as even viable.
>>>>>
>>>>
>>>> 4) Explicit declaration. In this approach we detect nothing and rely on
>>>
>>> the
>>>>>
>>>>> plugin developer to do everything. That is, they must provide
>>>>> somewhere
>>>>> (either in code or a configuration file) an index of all classes they
>>>>> offer,
>>>>> the interfaces they implement, and the file in which they live. While
>>>
>>> this
>>>>>
>>>>> makes the implementation easy, it is a huge burden on the plugin
>>>
>>> developer
>>>>>
>>>>> and
>>>>> I'm quite sure they'll forget to do so or get it wrong on a regular
>>>
>>> basis.
>>>>>
>>>>
>>>> I'd suggest combining 3 and 4. Build a tool that performs a static
>>>
>>> analysis
>>>>
>>>> of a group of files and make it easy for developers to use. This tool
>>>
>>> would
>>>>
>>>> generate the explicit declarations your codebase would utilize when
>>>> answering such questions as "which classes implement interface foo".
>>>> The
>>>> file the static analysis tool generates could be easily hand editable,
>>>> so
>>>> developers could tweak it if they see issues (just in case the static
>>>> analysis tool has bugs early on), or for small plugins, just quick crank
>>>
>>> out
>>>>
>>>> a couple lines by hand.
>>>>
>>>> As long as the static analysis tool builds a composite of class
>>>> hierarchy
>>>> established in all the files (project wide, at least in terms of the
>>>> plugin), you wouldn't have to double declare interfaces so they could be
>>>> detected.
>>>>
>>>> Adam
>
> That is essentially #3. The static analysis results could easily be cached
> in a human-editable form, but in practice I don't think that will be viable.
> The humans who will be running this system will largely be non-PHP-gurus so
> asking them to validate the accuracy of a giant PHP array dumped to a file
> is going to be a losing battle. If we're actually building a full graph to
> determine indirect implementation that would then preclude pre-deriving
> information per-plugin and just shipping a manifest file with each plugin.
> (I could be convinced of that as an approach, but that still doesn't solve
> the indirect implementation problem.)
>
>
>>> There is a pecl extension called inclued [1]& [2] which could be used I
>>> think.
>>>
>>> It can be used to produce a list of all the relationships between
>>> included files, so a one off pass of all the class files (simply
>>> include them) and then retrieve the analysis from inclued.
>>>
>>> You can now build a class dependency tree from that data and cache it.
>>>
>>> Pretty much exactly what you need.
>>>
>>
>> Richard,
>>
>> While inclued performs a nice analysis of the files included at a given
>> stage of a script, I don't see that it performs a static analysis of the
>> PHP
>> contained within the files so Larry could use it to detect the interfaces
>> implemented in a given set of PHP files.
>>
>> I looked at the pages:
>> http://docs.php.net/manual/en/inclued.examples-implementation.php
>> http://docs.php.net/manual/en/function.inclued-get-data.php
>>
>> I'm curious about this feature myself, so if I missed something, please
>> let
>> me know.
>>
>> Thanks,
>>
>> Adam
>
> Yeah, inclued looks cool but it looks like a runtime analysis tool, not a
> static analysis tool. That runs into the same problem as reflection where
> I'd have to include the whole code base in order to build up the indexes I
> need.
>
> --Larry Garfield
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
You would only need to do analysis by reflection once per release
though? Just like you would do to build your documentation (using
something like phpdoc for example). You _do_ document your code don't
you???
--
Richard Quadling
Twitter : EE : Zend
@RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
--- End Message ---
--- Begin Message ---
On Wed, Jan 19, 2011 at 11:23 AM, [email protected] <
[email protected]> wrote:
> On 1/19/11 10:09 AM, Adam Richardson wrote:
>
>> On Wed, Jan 19, 2011 at 8:21 AM, Richard Quadling<[email protected]
>> >wrote:
>>
>> On 19 January 2011 07:46, Adam Richardson<[email protected]> wrote:
>>>
>>>> On Wed, Jan 19, 2011 at 2:07 AM, Larry Garfield<[email protected]
>>>> wrote:
>>>>
>>>> 3) Static analysis. Instead of reflection, either tokenize or string
>>>>>
>>>> parse
>>>
>>>> all files to determine what classes implement what interfaces and then
>>>>> cache
>>>>> that information. We are actually using this method now to locate
>>>>>
>>>> classes,
>>>
>>>> and it works surprisingly well. Because we never parse code into memory
>>>>>
>>>> it
>>>
>>>> does not ever spike the memory usage. However, it is impossible to
>>>>> determine
>>>>> if a class implements a given interface by static analysis unless it
>>>>> declare
>>>>> so itself with the implements keyword. If it does so indirectly via
>>>>> inheritance, either via the class or via the interface, it would not
>>>>>
>>>> find
>>>
>>>> it.
>>>>> That necessitates that any "detectable" classes must explicitly
>>>>>
>>>> themselves
>>>
>>>> declare their interfaces, even if it is redundant to do so. I don't
>>>>>
>>>> like
>>>
>>>> that
>>>>> approach, but it's the first one that strikes me as even viable.
>>>>>
>>>>>
>>>> 4) Explicit declaration. In this approach we detect nothing and rely on
>>>>
>>> the
>>>
>>>> plugin developer to do everything. That is, they must provide somewhere
>>>>> (either in code or a configuration file) an index of all classes they
>>>>> offer,
>>>>> the interfaces they implement, and the file in which they live. While
>>>>>
>>>> this
>>>
>>>> makes the implementation easy, it is a huge burden on the plugin
>>>>>
>>>> developer
>>>
>>>> and
>>>>> I'm quite sure they'll forget to do so or get it wrong on a regular
>>>>>
>>>> basis.
>>>
>>>>
>>>>>
>>>> I'd suggest combining 3 and 4. Build a tool that performs a static
>>>>
>>> analysis
>>>
>>>> of a group of files and make it easy for developers to use. This tool
>>>>
>>> would
>>>
>>>> generate the explicit declarations your codebase would utilize when
>>>> answering such questions as "which classes implement interface foo".
>>>> The
>>>> file the static analysis tool generates could be easily hand editable,
>>>> so
>>>> developers could tweak it if they see issues (just in case the static
>>>> analysis tool has bugs early on), or for small plugins, just quick crank
>>>>
>>> out
>>>
>>>> a couple lines by hand.
>>>>
>>>> As long as the static analysis tool builds a composite of class
>>>> hierarchy
>>>> established in all the files (project wide, at least in terms of the
>>>> plugin), you wouldn't have to double declare interfaces so they could be
>>>> detected.
>>>>
>>>> Adam
>>>>
>>>
> That is essentially #3.
Well, actually the method I was describing (all so poorly) was a hybrid, as
I was suggesting that each plugin have a manifest, it's just that you'd
build a tool to help them generate it the manifest.
> The static analysis results could easily be cached in a human-editable
> form, but in practice I don't think that will be viable. The humans who
> will be running this system will largely be non-PHP-gurus so asking them to
> validate the accuracy of a giant PHP array dumped to a file is going to be a
> losing battle.
My suggestion to make it human-readable/editable was for the sake of plugin
developers, not general users who might install the system.
> If we're actually building a full graph to determine indirect
> implementation that would then preclude pre-deriving information per-plugin
> and just shipping a manifest file with each plugin. (I could be convinced
> of that as an approach, but that still doesn't solve the indirect
> implementation problem.)
Given the current information, I think building a tool that performs the
static analysis of interfaces per plugin and then providing that tool to
developers so they can build a manifest required per plugin is the best
alternative. It minimizes the performance issues by working plugin by
plugin, provides flexibility for future information to be included in the
manifest if it's ever needed, and could be a user friendly option for
developers.
Anyways, thanks for sharing your problem, Larry. It's nice to ponder such
things. You've shown yourself to be a very capable developer through your
comments to the list, and I'm sure whatever approach you take will work
well.
Adam
--
Nephtali: A simple, flexible, fast, and security-focused PHP framework
http://nephtaliproject.com
--- End Message ---
--- Begin Message ---
On 1/19/11 11:16 AM, Adam Richardson wrote:
As long as the static analysis tool builds a composite of class
hierarchy
established in all the files (project wide, at least in terms of the
plugin), you wouldn't have to double declare interfaces so they could be
detected.
Adam
That is essentially #3.
Well, actually the method I was describing (all so poorly) was a hybrid, as
I was suggesting that each plugin have a manifest, it's just that you'd
build a tool to help them generate it the manifest.
Well, I don't know if it's feasible to do a deep tree at module dev time
individually. To clarify, the code base in question has some 2000+
plugins, of which about 100 may be enabled at any given time on a
particular installation. That means building the manifest for an
individual plugin would require a very extensive build of the entire
development installation for that plugin. A particular class could
implement an interface provided by another plugin, which in turn
inherits from another, which inherits from a core system interface. I'm
just worried that the build process would become very onerous and/or
expensive.
If we kept the "explicit if redundant declaration" requirement, that
makes the rebuild much simpler. I guess that would have to be examined
experimentally.
If we're actually building a full graph to determine indirect
implementation that would then preclude pre-deriving information per-plugin
and just shipping a manifest file with each plugin. (I could be convinced
of that as an approach, but that still doesn't solve the indirect
implementation problem.)
Given the current information, I think building a tool that performs the
static analysis of interfaces per plugin and then providing that tool to
developers so they can build a manifest required per plugin is the best
alternative. It minimizes the performance issues by working plugin by
plugin, provides flexibility for future information to be included in the
manifest if it's ever needed, and could be a user friendly option for
developers.
Anyways, thanks for sharing your problem, Larry. It's nice to ponder such
things. You've shown yourself to be a very capable developer through your
comments to the list, and I'm sure whatever approach you take will work
well.
Eh? I barely comment on this list these days. :-) But thanks.
--Larry Garfield
--- End Message ---
--- Begin Message ---
On 1/19/11 10:52 AM, Richard Quadling wrote:
There is a pecl extension called inclued [1]& [2] which could be used I
think.
It can be used to produce a list of all the relationships between
included files, so a one off pass of all the class files (simply
include them) and then retrieve the analysis from inclued.
You can now build a class dependency tree from that data and cache it.
Pretty much exactly what you need.
Richard,
While inclued performs a nice analysis of the files included at a given
stage of a script, I don't see that it performs a static analysis of the
PHP
contained within the files so Larry could use it to detect the interfaces
implemented in a given set of PHP files.
I looked at the pages:
http://docs.php.net/manual/en/inclued.examples-implementation.php
http://docs.php.net/manual/en/function.inclued-get-data.php
I'm curious about this feature myself, so if I missed something, please
let
me know.
Thanks,
Adam
Yeah, inclued looks cool but it looks like a runtime analysis tool, not a
static analysis tool. That runs into the same problem as reflection where
I'd have to include the whole code base in order to build up the indexes I
need.
--Larry Garfield
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
You would only need to do analysis by reflection once per release
though? Just like you would do to build your documentation (using
something like phpdoc for example). You _do_ document your code don't
you???
Yes, the project is very heavily documented, and I can be rather OCD
about my Docblocks. :-)
The release cycle for the core system and plugins is not the same,
though. Plugins are written on their own schedule and updated whenever.
That means we'd need to, at minimum, do a rebuild of an individual
plugin at release time and build its manifest, which is still a
potentially expensive operation.
Actually, thinking about it, since we cannot guarantee a file location
we cannot guarantee a working autoload for reflection until after the
index is built that autoload can use. That would rule out any sort of
reflection approach that doesn't involve loading every PHP file we can
find. Doing that individually for every plugin when it's released could
get extremely expensive.
Also, a PECL module is not an option unless it's possible to make a
runtime version of it that can be swapped in, since we cannot guarantee
the server environment we're running on beyond stock PHP. :-( (Such is
life in the open source platform world.)
--Larry Garfield
--- End Message ---
--- Begin Message ---
What about creating your own docblock tag such as @plugin-interface? While
it still requires each plugin to explicitly define the interface(s) it
implements, it won't be in the class declaration. This would be very easy to
nab for a tree of files using grep, removing the need to do any static
analysis or parse PHP code.
David
--- End Message ---
--- Begin Message ---
On 1/19/11 3:44 PM, David Harkness wrote:
What about creating your own docblock tag such as @plugin-interface? While
it still requires each plugin to explicitly define the interface(s) it
implements, it won't be in the class declaration. This would be very easy to
nab for a tree of files using grep, removing the need to do any static
analysis or parse PHP code.
David
I'm not sure I see the advantage of that over specifying the interface
in the code:
/**
* Bob does stuff.
*
* @implements Foo
*/
class Bob implements Foo {
}
Either way developers need to explicitly define which interfaces (of
those we care about) the class implements, and we'll have to string
parse the file to find the string "Foo". As far as I know the extra
implements in the class declaration doesn't hurt PHP, it's just redundant.
And actually, thinking about it, I wonder if requiring the explicit
declaration is a good thing anyway because then it's immediately obvious
and greppable what the class does. :-)
--Larry Garfield
--- End Message ---
--- Begin Message ---
How often would this profiling have to happen? Seems to me that if
it's a "once per build" or "once per someone pressing the button",
then go for the more expensive analysis checking through the files.
Just build up a tree that shows which classes implement what or
inherit from where, save that along with file modification times, and
if you have to redo the analysis (on a running system, for instance)
then just check files that have changed since last check. It'll likely
be expensive once, but probably not very much (after all, you only
care about class, you don't need to parse docblocks or anything like
it).
regards
Peter
--
<hype>
WWW: plphp.dk / plind.dk
LinkedIn: plind
BeWelcome/Couchsurfing: Fake51
Twitter: kafe15
</hype>
--- End Message ---
--- Begin Message ---
> -----Original Message-----
> From: [email protected] [mailto:[email protected]]
> Sent: Wednesday, January 19, 2011 2:21 PM
> To: [email protected]
> Subject: Re: [PHP] Class and interface location
>
> On 1/19/11 3:44 PM, David Harkness wrote:
> > What about creating your own docblock tag such as @plugin-interface?
> > While it still requires each plugin to explicitly define the
> > interface(s) it implements, it won't be in the class declaration. This
> > would be very easy to nab for a tree of files using grep, removing the
> > need to do any static analysis or parse PHP code.
> >
> > David
>
> I'm not sure I see the advantage of that over specifying the interface in
the
> code:
>
> /**
> * Bob does stuff.
> *
> * @implements Foo
> */
> class Bob implements Foo {
>
> }
>
> Either way developers need to explicitly define which interfaces (of those
> we care about) the class implements, and we'll have to string parse the
file
> to find the string "Foo". As far as I know the extra implements in the
class
> declaration doesn't hurt PHP, it's just redundant.
>
> And actually, thinking about it, I wonder if requiring the explicit
declaration
> is a good thing anyway because then it's immediately obvious and
> greppable what the class does. :-)
>
> --Larry Garfield
>
You mean requiring explicit declaration of
> class Bob implements Foo {
>
> }
It's so you can guarantee your app from future breakage because the
interface guarantees minimum functionality and still maintain great
flexibility such that:
interface IDatabase
{
function connect();
function close();
function query();
// etc....
}
class MySQLDatabase implements IDatabase
{
function connect() { }
function close() { }
function query() { }
// other interface methods
function nonInterfaceMethod() { }
}
class PostgresDatabase implements IDatabase
{
function connect() { }
function close() { }
function query() { }
// other interface methods
function nonInterfaceMethod() { }
}
class MyObjectMapper extends MySQLDatabase
{
function getAll() { }
function edit() {}
// etc...
}
class Process
{
function _init(IDatabase $db)
{
$db->connect();
$db->query();
$db->close();
}
function exec() { }
// etc...
}
class PhonyObject
{
// miscellaneous methods even if the methods match exactly as the
IDatabase
}
$mdb = new MySQLDatabase();
$pdb = new PostgresDatabase();
$mom = new MyObjectMapper();
$phony = new PhonyObject();
$p = new Process();
$p->_init($mdb); // works
$p->_init($pdb); // works
$p->_init($mom); // works
$p->_init($phony); // fatal error
Hence the `I` in the API. The interface prevents from app breakage because
all classes must have matching method name(s) and the respective function
call parameters. Though, because PHP isn't a strong typed language like
C/C++/C#, Java, etc... the return value type, if any, _may_ break the app
;)
Regards,
Tommy
PS: outlook may wrap the lines... it happened once/twice before.
--- End Message ---
--- Begin Message ---
On Wednesday, January 19, 2011 8:56:50 pm Tommy Pham wrote:
> > And actually, thinking about it, I wonder if requiring the explicit
> declaration
> > is a good thing anyway because then it's immediately obvious and
> > greppable what the class does. :-)
> >
> > --Larry Garfield
>
> You mean requiring explicit declaration of
>
> > class Bob implements Foo {
> >
> > }
>
> It's so you can guarantee your app from future breakage because the
> interface guarantees minimum functionality and still maintain great
> flexibility such that:
Well, let me offer a more precise example of what I want to do:
interface Stuff {
function doStuff($a);
}
interface Things extends Stuff {
function doThings($a);
}
class Bob implements Stuff {...}
class Alice implements Stuff {...}
class George {}
class Matt implements Things {...}
function make_stuff_happen($o) {
foreach (class_that_implements_stuff() as $class) {
$c = new $class();
$c->doStuff($o);
}
}
The above code should iterate over Bob, Alice, and Matt, but not George. The
trick is how to implement class_that_implements_stuff() (or rather,
class_that_implements_something('Stuff')) in a sane and performant fashion
that supports auto-loading.
If all of the above is together in a single file, it's dead simple with
get_declared_classes() and class_implements(). However, in practice there
could be some 200 interfaces -- with each installation having a different set
of them -- and as many as 500 classes implementing some combination of those
interfaces, possibly multiple on the same class -- also with each installation
having a different set of them. I do not want to be forced to include all of
those classes and interfaces on every page load when in practice only perhaps
two dozen will be needed on a particular request. That makes
class_that_implements_stuff() considerably tricker.
That let naturally to having a cached index (in a database, in a file with a
big lookup array, whatever) that pre-computed which class implements what
interface and what file it lives in, so that we can easily lookup what classes
we need and then let the autoloader find them. (Previous benchmarks have
shown that an index-based autoloader is actually pretty darned fast.) That
just makes building that index the challenge, hence this email thread.
Thinking it through, however, I am now wondering if, in practice, indirect
implementation (class Matt above) will even be that common. It may not be
common enough to be an issue in practice, so requiring Matt to be declared as:
class Matt implements Stuff, Things {...}
isn't really that big of a deal and makes the indexer considerably simpler.
We actually have one already that indexes class locations; it just doesn't
track interfaces.
I also, on further review, don't think that class-based inheritance will ever
be an issue. The following:
class Mary extends Alice {...}
Would not make much sense at all because then both Mary and Alice would run,
so Alice's code would run twice. So I may be over-complicating the situation.
(For those following along at home, yes, this is essentially observer pattern.
However, it's on a very large scale and the thing being observed may not
always be an object, so the usual active registration process of instantiating
both objects and telling them about each other on the off chance that they
*may* be needed is excessively wasteful.)
Does that make it clearer what I'm trying to do?
--Larry Garfield
--- End Message ---
--- Begin Message ---
The newsgroup server seems to have a repeated-visit throttle, or whatever.
For the last two weeks at least, I can only open 2 or 3 messages and them I get
repeated time-outs. It acts like the DoS or flood prevention is kidding in to
aggressively.
Al..........
--- End Message ---