# Extention_Dir

- Thread: https://externals.io/message/37559
- Original archive: https://news-web.php.net/php.internals/37559
- Started by Hector Santos on 2008-05-09T10:04:13+00:00
- Messages: 14
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #37559 — Hector Santos — 2008-05-09T10:04:13+00:00

URL: https://externals.io/message/37559#37559

I'm relatively new to PHP development. I hope this is the appropriate 
area for this question since I was thinking maybe I could use the 
opportunity to get involved with the internals by making a patch 
regarding how DLLs are loaded.

Specifically, the extension_dir="path" directive which only allows a 
single path for finding dlls.

I'm nearly done with a new Windows-based PHP extension (php_wildcat.dll) 
and one of the issues was DLL dependencies.

The PHP extension offers direct SDK/API support for our application 
server and all our DLLs are in a specific server folder.

The installation of the Extension is preferred to be placed in our 
server folder so ideally,  something like so would be ideal:

    extension_dir="./ext;c:/wildcat"

But of course, this isn't supported and it will not work, in fact, it 
fails the loading of other PHP extensions.

The official method of placing extensions in the PHP "./Ext" requires 
that we alter our long (12 years) recommended policy of a) not copying 
our DLLS to other folders (for auto update/version control reasons) or 
not requiring of adding the server folder in the Windows PATH.

I came up with an somewhat "kludgy" solution but I somewhat feel this 
has to be a common PHP extension issues with extension authors, thus 
maybe I must of a missed something where I don't have to do any of this.

The solution I came up with is to use DELAY LOADING where the extension 
is compiled and linked with delayed loading of implicit dlls.

For example: the extension is compiled/linked using pragma directives 
like so:

#define USE_DELAY_LOADING
...
#ifdef USE_DELAY_LOADING
#  pragma comment(lib, "delayimp.lib")
#  pragma comment(linker, "/delayload:wcsrv2.dll")
#  pragma comment(linker, "/delayload:door32.dll")
#endif

delayimp.lib is part of the VC6.0 C/C++ runtime library and it handles 
the delayed implicit loading of dlls.  The DLLs above are part of our 
RPC server API interface.

Now, our RPC server folder is recorded in the registry so using the dll 
entry point DllMain(),  the registry location is read and this is used 
to add to the process environment path.  So I have this at the end of my 
PHP_WILDCAT.CPP code:

#ifdef USE_DELAY_LOADING

#define GETENV GetEnvironmentVariable
#define SETENV SetEnvironmentVariable

BOOL GetRegistry(const TCHAR *key,
                  const TCHAR *name,
                  DWORD type,
                  void *data,
                  DWORD datasize)
{
   BOOL ok = FALSE;
   HKEY k;
   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
             key, 0, KEY_READ, &k) == ERROR_SUCCESS) {
     DWORD t;
     if (RegQueryValueEx(k, (TCHAR *)name,  NULL,
             &t, (BYTE *)data, &datasize) == ERROR_SUCCESS) {
       ok = t == type;
     }
     RegCloseKey(k);
   }
   return ok;
}

BOOL GetRegistryString(const TCHAR *name,
                        TCHAR *data,
                        DWORD datasize,
                        const TCHAR *key = "SOFTWARE\\SSI\\Wildcat")
{
   return GetRegistry(key, name, REG_SZ, data, datasize);
}

BOOL PrepareWildcatPath()
{
    char srvPath[MAX_PATH]={0};
    if (GetRegistryString("ServerDirectory",srvPath,MAX_PATH-1)) {
       char ePath[1024*4] = {0};
       strcpy(ePath,srvPath);
       strcat(ePath,";");
       DWORD dw = strlen(ePath);
       return (GETENV("PATH",&ePath[dw],sizeof(ePath)-dw) &&
               SETENV("PATH",ePath));
    }
    return FALSE;
}

////////////////////////////////////////////////////////////////////
// DllMain
////////////////////////////////////////////////////////////////////

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID)
{
   switch (dwReason) {
     case DLL_PROCESS_ATTACH:
       PrepareWildcatPath();
       break;
   }
   return TRUE;
}

#endif

This works really well. We can install PHP*.DLLs in the PHP "./EXT" 
folder and when the extension is loaded by PHP,  all of its dependencies 
  are now resolved during the temporary PHP runtime residence time.

I could of gone deeper (and more elegant without having to alter the 
process PATH) by using the delayimp.lib helper hooks available which 
will issue a callback for the delayed implicit dlls.  But seems overly 
complexed and before I begin on that I wanted so see if a) there was 
already a method to address this and/or b) I could patch PHP to offer an 
multi-path extension_dir method.

Ideally we would love to keep our specific PHP*.DLL files in our server 
folder and have extension_dir defined to look at multiple paths.

Comments?

TIA

-- 
Hector Santos

---

## #37569 — Hector Santos — 2008-05-10T00:39:06+00:00

URL: https://externals.io/message/37559#37569 · In reply to: #37559

I probably over did my past post.

Let me simply ask, do you think there is technical merit (worth while) 
to create a patch which offers multi-directory DLL loading support for 
the PHP.INI extension_dir= option?

Example:

     extension_dir="./ext;c:/myserver/bin;c:/otherext"

Reasons:

Currently, it only allows for a single folder and this present some 
support issues.

But offering multi-directory support, PHP can:

   1) Reduce extension DLL (non-PHP related) dependency issues,
   2) Better support for PHP integration with Application Servers, and
   3) Better support for security isolation, sand-boxing applications.

Do you see a technical reason why this is not a good idea? Would it be 
transparent enough that it would not cause issues with current extensions?

TIA

--
Hector


Hector Santos wrote:
> I'm relatively new to PHP development. I hope this is the appropriate 
> area for this question since I was thinking maybe I could use the 
> opportunity to get involved with the internals by making a patch 
> regarding how DLLs are loaded.
> 
> Specifically, the extension_dir="path" directive which only allows a 
> single path for finding dlls.
> 
> I'm nearly done with a new Windows-based PHP extension (php_wildcat.dll) 
> and one of the issues was DLL dependencies.
> 
> The PHP extension offers direct SDK/API support for our application 
> server and all our DLLs are in a specific server folder.
> 
> The installation of the Extension is preferred to be placed in our 
> server folder so ideally,  something like so would be ideal:
> 
>    extension_dir="./ext;c:/wildcat"
> 
> But of course, this isn't supported and it will not work, in fact, it 
> fails the loading of other PHP extensions.
> 
> The official method of placing extensions in the PHP "./Ext" requires 
> that we alter our long (12 years) recommended policy of a) not copying 
> our DLLS to other folders (for auto update/version control reasons) or 
> not requiring of adding the server folder in the Windows PATH.
> 
> I came up with an somewhat "kludgy" solution but I somewhat feel this 
> has to be a common PHP extension issues with extension authors, thus 
> maybe I must of a missed something where I don't have to do any of this.
> 
> The solution I came up with is to use DELAY LOADING where the extension 
> is compiled and linked with delayed loading of implicit dlls.
> 
> For example: the extension is compiled/linked using pragma directives 
> like so:
> 
> #define USE_DELAY_LOADING
> ...
> #ifdef USE_DELAY_LOADING
> #  pragma comment(lib, "delayimp.lib")
> #  pragma comment(linker, "/delayload:wcsrv2.dll")
> #  pragma comment(linker, "/delayload:door32.dll")
> #endif
> 
> delayimp.lib is part of the VC6.0 C/C++ runtime library and it handles 
> the delayed implicit loading of dlls.  The DLLs above are part of our 
> RPC server API interface.
> 
> Now, our RPC server folder is recorded in the registry so using the dll 
> entry point DllMain(),  the registry location is read and this is used 
> to add to the process environment path.  So I have this at the end of my 
> PHP_WILDCAT.CPP code:
> 
> #ifdef USE_DELAY_LOADING
> 
> #define GETENV GetEnvironmentVariable
> #define SETENV SetEnvironmentVariable
> 
> BOOL GetRegistry(const TCHAR *key,
>                  const TCHAR *name,
>                  DWORD type,
>                  void *data,
>                  DWORD datasize)
> {
>   BOOL ok = FALSE;
>   HKEY k;
>   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
>             key, 0, KEY_READ, &k) == ERROR_SUCCESS) {
>     DWORD t;
>     if (RegQueryValueEx(k, (TCHAR *)name,  NULL,
>             &t, (BYTE *)data, &datasize) == ERROR_SUCCESS) {
>       ok = t == type;
>     }
>     RegCloseKey(k);
>   }
>   return ok;
> }
> 
> BOOL GetRegistryString(const TCHAR *name,
>                        TCHAR *data,
>                        DWORD datasize,
>                        const TCHAR *key = "SOFTWARE\\SSI\\Wildcat")
> {
>   return GetRegistry(key, name, REG_SZ, data, datasize);
> }
> 
> BOOL PrepareWildcatPath()
> {
>    char srvPath[MAX_PATH]={0};
>    if (GetRegistryString("ServerDirectory",srvPath,MAX_PATH-1)) {
>       char ePath[1024*4] = {0};
>       strcpy(ePath,srvPath);
>       strcat(ePath,";");
>       DWORD dw = strlen(ePath);
>       return (GETENV("PATH",&ePath[dw],sizeof(ePath)-dw) &&
>               SETENV("PATH",ePath));
>    }
>    return FALSE;
> }
> 
> ////////////////////////////////////////////////////////////////////
> // DllMain
> ////////////////////////////////////////////////////////////////////
> 
> BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID)
> {
>   switch (dwReason) {
>     case DLL_PROCESS_ATTACH:
>       PrepareWildcatPath();
>       break;
>   }
>   return TRUE;
> }
> 
> #endif
> 
> This works really well. We can install PHP*.DLLs in the PHP "./EXT" 
> folder and when the extension is loaded by PHP,  all of its dependencies 
>  are now resolved during the temporary PHP runtime residence time.
> 
> I could of gone deeper (and more elegant without having to alter the 
> process PATH) by using the delayimp.lib helper hooks available which 
> will issue a callback for the delayed implicit dlls.  But seems overly 
> complexed and before I begin on that I wanted so see if a) there was 
> already a method to address this and/or b) I could patch PHP to offer an 
> multi-path extension_dir method.
> 
> Ideally we would love to keep our specific PHP*.DLL files in our server 
> folder and have extension_dir defined to look at multiple paths.
> 
> Comments?
> 
> TIA

---

## #37572 — Lars Strojny — 2008-05-10T12:41:04+00:00

URL: https://externals.io/message/37559#37572 · In reply to: #37569

Hi Hector,

Am Freitag, den 09.05.2008, 20:39 -0400 schrieb Hector Santos:
[...]
> Do you see a technical reason why this is not a good idea? Would it be
> transparent enough that it would not cause issues with current
> extensions?

I would really love to see this. A use case I have in mind is extension
development. If one has a continuous integration solution, the in-house
developed module can be easily auto-deployed and live with system-wide
default extensions.

cu, Lars

---

## #37574 — Hector Santos — 2008-05-10T17:43:19+00:00

URL: https://externals.io/message/37559#37574 · In reply to: #37572

Lars Strojny wrote:
> Hi Hector,
> 
> > […]
> 
> I would really love to see this. A use case I have in mind is extension
> development. If one has a continuous integration solution, the in-house
> developed module can be easily auto-deployed and live with system-wide
> default extensions.
> 
> cu, Lars

Great! Got two positives on this, so I'll work on this.  Now, if I can 
only figure out the Windows Build.  What a mess!!  :-)

-- 
Hector Santos

---

## #37575 — Elizabeth M Smith — 2008-05-10T18:39:19+00:00

URL: https://externals.io/message/37559#37575 · In reply to: #37574

Hector Santos wrote:
> Lars Strojny wrote:
> > […]
> 
> Great! Got two positives on this, so I'll work on this.  Now, if I can
> only figure out the Windows Build.  What a mess!!  :-)
> 
Actually building for windows is easy - it's the dependencies that are
hard ;)  check out the wiki for build help

Thanks
Elizabeth

---

## #37576 — Hector Santos — 2008-05-11T04:43:06+00:00

URL: https://externals.io/message/37559#37576 · In reply to: #37575

(Elizabeth, this is a public follow up to the previous message (shown 
below))

Of course, I must not be doing something right, but I was finally able 
to compile and successful link by:

1) Adding pcrec_newline.c to the project PCRE source group #3

2) Adding a #include "config.h" to pcre_internal.h
    to resolve the LINK_SIZE define

3) Adding tokenizer_data.c to the project XML source group #4

4) Changing the link lib "libxml2_a.lib" to libxml2_a_dll.lib which 
probably means libxml2.dll will be used with php5ts.dll

5) And to resolve the _ftol2 link libxml2 error, add the following chunk 
to ext\dom\xpath.c:

// HLS, only for MSDEV 6.0
#if (_MSC_VER == 1200)
extern long _ftol( double ); //defined by VC6 C libs
extern long _ftol2( double dblSource ) { return _ftol(dblSource ); }
#endif

6) I also had to alter the INCLUDE paths for some of the projects where 
it was using a ..\..\FOLDER entry to ..\FOLDER.   I often find this to 
be a common issue with DSP projects under the vs 6.0 IDE because of the 
stock File OPEN/SAVE dialog not restoring the original directory.  When 
include references are adding, the programmer needs to make sure the 
proper project ROOT folder is set when the project is saved so that it 
can create and establish the proper persistent paths. IOW, when you add 
a file to a project source folder and you had to switch directories, the 
IDE is implementing OPEN/SAVE dialog to remember this location and this 
can alter how include file are found when using relatives INCLUDE paths.

Anyway, not sure if any of the above is note worthy but if I am going to 
be doing more PHP work, maybe I can contribute by providing a 
"no-hassle" windows build.

-- 
Hector Santos


Elizabeth M Smith wrote:

> > […]
> Actually building for windows is easy - it's the dependencies that are
> hard ;)  check out the wiki for build help

Yes, I had to go get else where libxml, iconv, and soemthing else (I
think it was bindlib_win32).  I wasn't quite sure if the instructions
assumed cygwin makefile prepareness or the VS *.DSP/DSW files were
independent of this.  Various projects had conflicting include and lib
paths.

But after working all that out, I am at this final linkage error where I
am don't know what else I can I can do beyond the changes already done
to the project build, and searching/collecting all the other dependencies.

linking...
    Creating library ..\Release_TS/php5ts.lib and object
..\Release_TS/php5ts.exp
LINK : warning LNK4049: locally defined symbol "_php_dom_create_object"
imported
pcre_compile.obj : error LNK2001: unresolved external symbol
__pcre_is_newline
pcre_exec.obj : error LNK2001: unresolved external symbol __pcre_is_newline
pcre_exec.obj : error LNK2001: unresolved external symbol __pcre_was_newline
tokenizer.obj : error LNK2001: unresolved external symbol
_tokenizer_register_constants
tokenizer.obj : error LNK2001: unresolved external symbol
_get_token_type_name
spl_iterators.obj : error LNK2001: unresolved external symbol _php_pcre_exec
php_pcre.obj : error LNK2001: unresolved external symbol _php_pcre_exec
php_pcre.obj : error LNK2001: unresolved external symbol _php_pcre_version
php_pcre.obj : error LNK2001: unresolved external symbol _php_pcre_study
php_pcre.obj : error LNK2001: unresolved external symbol _php_pcre_compile
php_pcre.obj : error LNK2001: unresolved external symbol
_php_pcre_maketables
php_pcre.obj : error LNK2001: unresolved external symbol _php_pcre_info
php_pcre.obj : error LNK2001: unresolved external symbol _php_pcre_free
php_pcre.obj : error LNK2001: unresolved external symbol
_php_pcre_get_substring_list
php_pcre.obj : error LNK2001: unresolved external symbol _php_pcre_fullinfo
libxml.obj : error LNK2001: unresolved external symbol _xmlDllMain
libxml2_a.lib(xpath.obj) : error LNK2001: unresolved external symbol __ftol2
libxml2_a.lib(xmlschemastypes.obj) : error LNK2001: unresolved external
symbol __ftol2
libxml2_a.lib(xpointer.obj) : error LNK2001: unresolved external symbol
__ftol2
..\Release_TS\php5ts.dll : fatal error LNK1120: 15 unresolved externals
Error executing link.exe.

php5ts.dll - 20 error(s), 1 warning(s)

pcrec_newline.c is not included int the project PREC source listing.
Adding it gives me a compiler error about LINK_SIZE not being set.

Adding this file to the project, adding #include "config.h" to it, gets
past this link resolution, but now it seems that I am going beyond what
was expected in the project build setup/provided for a successful build

I must not be doing something right.

-- 
Hector Santos

---

## #37605 — Hector Santos — 2008-05-12T13:25:42+00:00

URL: https://externals.io/message/37559#37605 · In reply to: #37574

Folks,

Well, I got this extension_dir logic work completed based on my PHP 
5.2.5 CVS copy of PHP.  The feature allows your to set the extension_dir 
for multiple paths.  This is what I had so far in PHP.INI-DIST/RECOMMENDED.

;---------------------------------------------------------------------
; Directory locations (paths) in which the loadable extensions (modules)
; reside. To add multiple paths, separate paths using ":" (UNIX) for
; ";" (Windows) character. Examples:
;
;   UNIX:    extension_dir = "/path1:/path2"
;   Windows: extension_dir = "\path1;\path2"
;
; Note: Explicit FQFN (Fully Qualified File Name) extension loading
;
:   Extensions with explicit FQFN can be used to skip the
;   extension search in the extension_dir path(s).
;   i.e.  extension = c:\serverapp\bin\php_wildcat.dll
;
;---------------------------------------------------------------------
extension_dir = "./ext"

The source code change was done on the ext\standard\dl.c file.

I was about to create the patches for the current PHP52, PHP53 and PHP6 
snapshots when I noticed there was a change in PHP53 that was done that 
allows for explicit FQFN extension= loading.

<side beef>
I don't know if this was a result of someone lurking the list and 
decided to go ahead and do this after reading the related recent thread 
for the multi-path extension_dir proposal, which is fine, but if they 
did go about this after seeing the thread, a simple courtesy to post a 
note of their intention would of been appreciated.  Things like this 
waste people's time.
</side beef>

In any case, to see if there was any other stuff related to this, I 
checked the bug database and found two related past feature request 
related to this:

   Bug # 22587 (Mar 2003) extension_path feature
   Bug # 41310 (May 2007) make extension_dir optional and use absolute
               paths in "extension = ..."

#22587 is pretty much what I am satisfying.

#41310 was interesting so I wanted to see if this was possible now.

Using my 5.2.5 release installation (which would be the same logic as 
5.2.6),  I tested the following PHP.INI option:

   extension_dir="./ext"
   extension_dir="../../php_wildcat.dll"

and of course, the source code logic show this as well.

But the PHP53 FQFN change now breaks this.

The PHP53 change allow for extension= module loading if the filename has 
a directory separator, but not supported for temporary loading via a PHP 
script `DL()` function.

    extension=c:\path\php_extension.dll   <== works under PHP53 only
    dl("c:\path\php_extension.dll")       <== never supported.

I personally think PHP53 change is more correct, but that depends on 
your point of view.  Should the filename loading be off the ROOT path 
for the PROCESS or off the extension_dir path was what the 5.2 logic.

It also depends on what the file name is:

    FQFN means a complete path (not relative)

There could be a change where if the file name has relative folder 
reference (../) then it could use the extension_dir as the root as it 
was supported in PHP52.  If its FQFN, then its a explicit load.

In all, this is what I think:

1) PHP53 breaks PHP52 logic.  Although "more correct", its breaks
    working code so we need to do something there.

2) Consider using a new extension_path to override extension_dir
    thereby keeping extension_dir PHP52 intact and only apply the
    multiple path search to the new extension_path, if defined.

3) Continue with the current patch I am doing with extension_dir
    and if a extension= has a relative path, apply this only to
    the FIRST path defined in extension_dir.  For example:

    extension_dir="./ext;c:/wildcat;c:/other"

    extension=php_zip.dll
    extension=php_wildcat.dll
    extension=../php_extension2.dll
    extension=c:\somewhere\php_extension3.dll

php_zip.dll has no folder information, so its found its stock ./ext folder.

php_wildcat.dll has no folder information, its not in ./ext so the 
additional paths are checked and its found in c:/wildcat

php_extension2.dll has a relative location, so to continue with PHP52 
expectations, it will only use the first path "./ext" as its root.

php_extension3.dll has a FQFN so its explicitly loaded with the FQFN.

Comment?  What path do you think its the best way?

Again, although PHP53 change logic seems to be more correct, IMO, that 
is would be so if PHP was new and there was no working code out there. 
But as it was done now, it does break the PHP52 logic.

-- 
Hector Santos

---

## #37608 — Stanislav Malyshev — 2008-05-12T17:31:40+00:00

URL: https://externals.io/message/37559#37608 · In reply to: #37569

Hi!

> Let me simply ask, do you think there is technical merit (worth while) 
> to create a patch which offers multi-directory DLL loading support for 
> the PHP.INI extension_dir= option?

extension is an one-time configuration directive. Since it allows full 
path now, how hard would it be to get it right with full path?
Multiple paths may contain some dangerous pitfalls - like, what happen 
if extension is in multiple paths, and in some it's not compatible 
(wrong version/debug/ts)? What if you have some old version lying around 
in fifth path, and you had new version in first path, but somehow 
permissions got mangled and it's not readable, so wrong version is 
loaded? Etc., etc. - it seems to have potential for many unpleasant 
moments.

>   1) Reduce extension DLL (non-PHP related) dependency issues,

How? I'd say, if you have extension A using foo.dll, and extension B 
using foo.dll, and they live in different directories, don't you now 
have to maintain two copies of foo.dll instead of one?

>   2) Better support for PHP integration with Application Servers, and

Here I'd like to hear more - how it helps PHP and Application Servers?

>   3) Better support for security isolation, sand-boxing applications

I'm not sure how giving multiple places to put security-sensitive stuff 
(extension has access to everything) improves sandboxing, could you explain?
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #37610 — Hector Santos — 2008-05-12T19:28:39+00:00

URL: https://externals.io/message/37559#37610 · In reply to: #37608

Stanislav Malyshev wrote:
> Hi!
> 
> > […]
> 
> extension is an one-time configuration directive. Since it allows full 
> path now, how hard would it be to get it right with full path?

In PHP52, it allows only relative paths:

     extension_dir="./ext"
     extension=../special/php_specialext.dll

Attempting to clear extension_dir does not work in an attempt to use a 
FQFN  (fully qualified file name).

Example, for FQFN extension

     extension=c:/php/special/php_specialext.dll

None of the following will works:

     extension_dir=""
     extension_dir=
     ;extension_dir=

PHP53 was updated to override the extension_dir= location IFF there is a
directory separator in the extension= file name.

> Multiple paths may contain some dangerous pitfalls - like, what happen 
> if extension is in multiple paths, and in some it's not compatible 
> (wrong version/debug/ts)? What if you have some old version lying around 
> in fifth path, and you had new version in first path, but somehow 
> permissions got mangled and it's not readable, so wrong version is 
> loaded? Etc., etc. - it seems to have potential for many unpleasant 
> moments.

Possible. But this is partly the reason why I think it applies, as I
will note below.

> > […]
> 
> How? I'd say, if you have extension A using foo.dll, and extension B 
> using foo.dll, and they live in different directories, don't you now 
> have to maintain two copies of foo.dll instead of one?

But if you are single sourcing foo.dll, why would you want to have 
multiple copies floating around?  Thats partially the point there, more 
importantly non-php related foo.dll is in one location outside of PHP.

Consider foo.dll to be a "system.dll" where only 1 version is expected, 
"DLL From Hell" issues.

> > […]
> 
> Here I'd like to hear more - how it helps PHP and Application Servers?

I'm a bit surprise you have to ask. :-)

> > […]
> 
> I'm not sure how giving multiple places to put security-sensitive stuff 
> (extension has access to everything) improves sandboxing, could you 
> explain?

Today, if an application server wish to implement PHP, it will need to 
add its PHP extensions into the single extension_dir location.

For an application server that traditionally does not desire for its 
DLLs to be floating outside its controlled environment, PHP does not 
play well here.

Our package is a long time integrated RPC client/server framework and, 
we keep everything under one secured folder.  No need for PATHS. No need 
to copy dlls. The primary reason is to control versions issues and 
customer auto updates into one known location - isolation.

With increase customer usage of PHP and 3rd party developer demand for
direct PHP support, for which we currently only provide generic 
CGI/script mapping support, we began to write an extension
to expose the 150+ server API to the PHP language and added PHP to our 
SDK suite of language support; C/C++, Java, VB, VFP, Delphi, .NET and 
now PHP.

Immediately we found isolation issues in regard

    - PHP library/classes,
    - DLL dependencies issues.

The include_path resolves the script issues, but we don't have the same 
flexibility with DLLs.

Our server is a RPC client/server system and each RPC client
requires our DLL interface files, including the new PHP extension we
wrote (a total of 3 of them) which are basically wrappers to our RPC
client dll API interface.

The unreleased package includes many PHP examples to illustrate how PHP
can work with our system and we found we have to either:

     a) copy our DLLS into PHP "extension_dir" folders,

     b) copy them to a windows PATHed folder,

     c) add a DELAY_LOADING concept to the PHP extensions which
        allow the extension's dll_main() process_attach logic
        to prepare finding its server dependencies.

The latter is how we currently have it working now, but not something we
really wanted to do because of the method it uses.

Since the above extension= full path idea does not work, we would left
(pressured) to look at the possibility of altering PHP itself.  Hence
why I am here.

We also expect to add direct embedded/sapi support and this will 100% 
require PHP to work around our centralized server focus, not an embedded 
language as the central focus.

I think the same will hold true in the application server growth market 
where PHP needs to fit into better, and not the other way around.

Thus far, I can provide a quick summary review of two items where I 
think PHP can be improved:

- multi-path extension_dir support

- PER application multi-ini include support. Scattered material seem
   to suggest this is possible, I have not seen how.

Think of an application server being "PHP Ready" with a PHP 
configuration file that is already available, always distributed.

If a customer wants to install PHP, all it needs to do is add a line 
such as:

   appserver_ini="c:\wcat\wcphp.ini"

or have a new INI folder concept:

   appserver_ini_dir="./ini"

where applications that place their specific INI and PHP will reads 
these INI files.

The ini will have the overriding PHP requirements, for example, this is 
the WCPHP.INI we add to the PHP.INI during installation for an existing 
PHP installation.   You can imagine the complexity in augmenting an 
integration with possibly existing other system setups, i.e, adding to 
the include_path= rather then replacing it, etc.

;----------------------------------------------------------
; wcPHP PHP.INI configuration file.
; minimum setup. see complete php-recommended.ini for
; more options
;----------------------------------------------------------

[PHP]

doc_root =
cgi.force_redirect = 0
cgi.fix_pathinfo=1

include_path =".;c:\wcat\php\code"
extension_dir =".\ext;c:\wcat"

extension=php_pdo.dll
extension=php_pdo_sqlite.dll

;----------------------------------------------------------
; PHP Wildcat! Extension
;----------------------------------------------------------

[wildcat]

allow_call_time_pass_reference = On

extension=php_wildcat.dll
extension=php_wscgate.dll
extension=php_wcdoor32.dll

; Wildcat.Server defined the server computer name to connect to
; Leave it blank to connect to the current server.
; Wildcat.AutoConnect flag allows to auto connnection and
; reestablishing the current user connect.

wildcat.server      = ""
wildcat.autoconnect = 0

;----------------------------------------------------------
; wcShareNet Configuration
;----------------------------------------------------------

[wcsharenet]

wcsharenet.pdo.drv = "sqlite"
wcsharenet.pdo.dbf ="c:/wcat/wcShareNet/wcShareNet.db"
wcsharenet.pdo.dsn = ""
wcsharenet.pdo.uid = ""
wcsharenet.pdo.pwd = ""

-- 
Hector Santos, CTO
Santronics Software, Inc.

---

## #37611 — Stanislav Malyshev — 2008-05-12T19:50:22+00:00

URL: https://externals.io/message/37559#37611 · In reply to: #37610

Hi!

> In PHP52, it allows only relative paths:

Right, but 5.2 is stable version so I don't see new features going 
there. Thus I think it's better to discuss 5.3 for new stuff, unless 
it's something so critical that it must be in 5.2.

> But if you are single sourcing foo.dll, why would you want to have 
> multiple copies floating around?  Thats partially the point there, more 
> importantly non-php related foo.dll is in one location outside of PHP.

I don't need multiple copies. But I may want to keep it in the same 
directory the extension is - otherwise I'd have to add the directory to 
windows path, which add overhead to install. By keeping all the stuff in 
the same directory, it'd work out of the box.

> Today, if an application server wish to implement PHP, it will need to 
> add its PHP extensions into the single extension_dir location.

Either that or use full paths in php.ini, depending on how the server is 
structured.

> For an application server that traditionally does not desire for its 
> DLLs to be floating outside its controlled environment, PHP does not 
> play well here.

Why? Just put all the stuff into that extension directory, if you talk 
about Windows. On Unix, .so resolution rules won't help here, but having 
extension path is not going to change anything.

> The include_path resolves the script issues, but we don't have the same 
> flexibility with DLLs.

I'm not sure what do you mean here. If you mean that PHP extensions use 
external DLLs, then you have two cases:
1. DLL is used only by PHP extension, nothing else uses it. Resolution: 
put it in the same directory PHP extensions are.
2. DLL is used by other stuff (external programs, etc.), not only PHP. 
Resolution: put it into separate library directory and add the directory 
in system PATH.

In both cases, I don't see how path for _extensions_ is helping you, 
unless all your application lives in the same directory and for some 
reason it's not possible to either add it to the path or use full pathes 
in php.ini extension= directives (but is possible in extension_dir 
directive).

>     a) copy our DLLS into PHP "extension_dir" folders,
>     b) copy them to a windows PATHed folder,

If it's external use DLLs, b) is the right way to go. It is regardless 
of the extension - if multiple parts of the application use same DLL, 
and they may reside in different directories, PATH is only way I can 
think of that makes it work.

> - PER application multi-ini include support. Scattered material seem
>   to suggest this is possible, I have not seen how.

You can do it in 5.3 with "user ini files", but it's not documented yet, 
unfortunately. Hopefully, it will be soon.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #37614 — Hector Santos — 2008-05-13T02:29:52+00:00

URL: https://externals.io/message/37559#37614 · In reply to: #37611

Stanislav Malyshev wrote:

> > […]
> 
> If it's external use DLLs, b) is the right way to go. It is regardless 
> of the extension - if multiple parts of the application use same DLL, 
> and they may reside in different directories, PATH is only way I can 
> think of that makes it work.

Its the only way to augment PHP.

I seriously doubt we are not going to change a 12 year design, 
operations and support policy of not requiring customers the need to use 
a PATH statement just to implement 3rd party solutions. It just not 
going to happen. PHP is not the central piece of the server framework.

If the current change to PHP53 is kept, which breaks PHP52, then we only 
have the choice of using a FQFN, which is fine, but that further means 
different versions of the PHP.INI setup.

So if you think the multi-path extension_dir= change isn't going to be 
accepted to PHP53, I might as well stop right here.

PS: I must say that I find it incredible that "breaking code" seems to 
be the modus operandi around here. I think the team should be more 
considerate of such issues and especially high-end corporate 
implementation needs if it wishes to be more friendly and cooperative as 
PHP moves on.

-- 
Hector Santos, CTO
Santronics Software, Inc.

---

## #37633 — Stanislav Malyshev — 2008-05-13T19:03:08+00:00

URL: https://externals.io/message/37559#37633 · In reply to: #37614

Hi!

> If the current change to PHP53 is kept, which breaks PHP52, then we only 

Here I must have missed something - which use case worked in 5.2 and not 
in 5.3? If we can make it work with 5.3 - we definitely should do it.

> So if you think the multi-path extension_dir= change isn't going to be 
> accepted to PHP53, I might as well stop right here.

I don't know - it depends how broad is the need for it and how other 
developers perceive it.

> PS: I must say that I find it incredible that "breaking code" seems to 
> be the modus operandi around here. I think the team should be more 

It is not. Of course, nobody here is omniscient, so it may happen on 
occasion that we do changes that may break some setups. Then the person 
whose code is broken writes to the list or submits a bug and complains - 
so&so worked before and doesn't work now. Then we see if the breakage 
was intentional (which happens sometimes - PHP is evolving and things 
that looked like good idea 5 years ago may not look so good now) or by 
mistake, and in the latter case we fix it. However nobody here does 
changes just for the heck of it.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #37660 — sean finney — 2008-05-15T07:00:54+00:00

URL: https://externals.io/message/37559#37660 · In reply to: #37633

hiya,

sorry to jump in a little late here,

On Tuesday 13 May 2008 09:03:08 pm Stanislav Malyshev wrote:
> > […]
>
> I don't know - it depends how broad is the need for it and how other
> developers perceive it.

just to throw in my 0.02 $LC_MONETARY, it would be really useful to have 
something like this in debian and other php-packaging distributions out 
there.

consider the scenario where a user installs via the package management system 
the php core plus extensions a, b, and c.  they later want to install 
extension d (which is not packaged) via pecl, and update/override extension 
c.

currently what happens is pecl (there's a similar situation with pear btw) 
installs to the same location as the packaged files, creating a rather 
schizophrenic environment where you can't be sure what came from a package 
and what was locally installed.  and further, the next time extension c's 
package is upgraded, the local changes will be lost.

now if there were a multi-extension-dir functionality available, we could do 
something like saying "first check /usr/local/blah, and if that fails, 
check /usr/blah", where the latter is for the debian stuff.  then pecl could 
be set to default to the /usr/local directory, eliminating the problem.  fwiw 
something quite similar is done by perl--i believe it provides 3 directories 
actually: a "perl" directory, a "vendor" directory, and a "site" directory, 
but it's the same concept.


anyway, hope to see something like this down the line!


	sean

---

## #37664 — Hector Santos — 2008-05-15T07:49:53+00:00

URL: https://externals.io/message/37559#37664 · In reply to: #37660

sean finney wrote:

> On Tuesday 13 May 2008 09:03:08 pm Stanislav Malyshev wrote:
>
> > […]
> 
> just to throw in my 0.02 $LC_MONETARY, it would be really useful to have 
> something like this in debian and other php-packaging distributions out 
> there.
> 
> consider the scenario where a user installs via the package management system 
> the php core plus extensions a, b, and c.  they later want to install 
> extension d (which is not packaged) via pecl, and update/override extension 
> c.
 >
 > ....
 >
> anyway, hope to see something like this down the line!

Thanks for your input Sean.

I have the change to ext\standard\dl.c working very nicely for PHP 5.2. 
I spent more time finally getting the building of PHP5TS.DLL under 
windows with the goal of reproducing an official release image (same 
exports, imports, built-in extensions, ect) so it would be a plug and 
play feature for anyone using PHP 5.2.  But I guess this will only by 
provided as a patch for PHP 5.2 since as I understand it, there would be 
  no more releases under PHP 5.2 (unless a critical/security bug was 
found).

I am now working on getting the new PHP 5.3 building process setup with 
its new pecl2 libraries, etc so once thats done, I'll patch dl.c for PHP 
5.3.

BTW, the technical outline semantics for this is:

   1) Secure dynamically modules (loaded via script)
      against filenames with paths.

   2) Allow explicit loading of persistent FQFN modules
      (but no relative path, no ".." in filename) or when
      the extension_dir is empty.

      Note: The problem here I don't see how you can create an
      empty extension_dir via the PHP.INI.  PHP seems to
      default implicitly to "C:\PHP5" string (literally) in
      the official builds. A blank, extension_dir="", does
      not work.

      If blank, it should do a WIN32 API call to

          GetModuleFileName(NULL,szPhpFileName, NULL)

      to get file location of the PHP EXE process, rather then use
      hard coded "C:\PHP5".

   3) Finally, parse the multiple paths, if any, attempt to
      load the parsed_path + filename.

The logic keeps with PHP 5.2 and the current PHP 5.3 change that allows 
for an explicit load if the filename contains slashes.  However, my 
change does not allow it if there are relative parts ("..") in the file 
name.  For (low) security reasons, relative paths should only be off an 
explicitly extension_dir="non_blank" definition as prepared by the local 
operator so there are no security surprises.

If fact, I could see a new option:

    extension_allow_relative_loads = No   <-- new default behavior

But it might be an overkill to add this.

-- 
Hector Santos, CTO
Santronics Software, Inc.
