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 ---

Reply via email to