I'm not going to lie. I'm not all the familiar with Windows and COM objects. That's why i'm here. First of all is it possible to access a DLL from within a PHP script running out of Apache? In my journey around the internets i believe that i have 2 options:
compile the dll as an extension for PHP. (i didn't make this dll)
access the DLL as a COM object which is sort of what it's designed for anyways.
So i'm taking the COM approach.
try{
$com = new COM('WHAT_GOES_HERE');
} catch(Exception $e){
echo 'error: ' . $e->getMessage(), "\n";
}
How do i go about finding out what would go into the initialization string? is there a com viewer type program i could/should be using to find this out? the documentation associated with this DLL doesn't seem to specify what strings i should be using to initialize but gets very in-depth into what streams are available, and all sorts of fun stuff. just gotta past this initial hump. Please help!
WHAT_GOES_HERE is the ProgID, Class ID or Moniker registered on the Operating System.
Each of these can change for the same DLL registered on different machines. There are several ways to find what's the ProgID/CLSID/Moniker of a registered dll. You can search the web for "dll debugger", "dll export", "dll inspect" and you'll see several solutions, and also ways to show what functions the dll export so you can use them.
The easiest way, you can just register the dll with Regsvr32.exe and search Window's register with regedit.exe for the dll's name, you might need to search several times until you find the key under \HKEY_CLASSES_ROOT\, which is the ProgID.
The command dcomcnfg.exe shows a lot of information about COM objects.
If you have Visual Studio, the OLE/COM Object Viewer (oleview.exe) might be useful.
You can run dll functions (from dlls which are not php extensions) with winbinder.
http://winbinder.org/
Using it is simple. You have to download php_winbinder.dll and include it in php.ini as an extension.
In the php script you have to use something similar:
function callDll($func, $param = "")
{
static $dll = null;
static $funcAddr = null;
if ($dll === null)
{
$dll = wb_load_library(<DLL PATH AND FILENAME>);
}
$funcAddr = wb_get_function_address($func, $dll);
if ($param != "")
{
return wb_call_function($funcAddr,array(mb_convert_encoding($param,"UTF-16LE")));
}
else
{
return wb_call_function($funcAddr);
}
}
You can simply develop a wrapper around your main dll and use this wrapper as an extension in your PHP. Some free tools like SWIG can generate this wrapper for you automatically by getting the header of your dll functions. I myself use this approach and it was easy and reliable.
With PHP>=7.4.0's new FFI/Foreign Function Interface (which didn't exist yet when this question was posted), this is now easier than ever before! For example, to call the GetCurrentProcessId(); function from kernel32.dll:
<?php
declare(strict_types=1);
$ffi = FFI::cdef(
'unsigned long GetCurrentProcessId(void);',
"C:\\windows\\system32\\kernel32.dll"
);
var_dump($ffi->GetCurrentProcessId());
outputs
C:\PHP>php test.php
int(24200)
:)
Related
I'm trying to understand what options are available for me in my configuration.nix for particular programs, by searching the pkgs sub-folder of nixpkgs's source tree, picking out the module's definitions to understand the available options. However, I'm running into a troublesome case for PHP - it's a special derivation, a composable derivation. I'm not able to see what options I have available with PHP - something that would be tremendously helpful for enabling special modules like mcrypt, gd, etc. Any help with this would be greatly appreciated!
It took me a while to figure this out but the right way to use composeDerivation for setting the php package build features is this:
# config.nix
{
packageOverrides = pkgs: rec {
php = pkgs.php.merge {
cfg = {
imapSupport = false;
intlSupport = false;
fpmSupport = false;
};
};
};
}
This overrides the default values in cfg specified in php/default.nix (imapSupport, intlSupport and fpmSupport get turned off). You can either place that file in ~/.nixpkgs/config.nix to be active system-wide or use it in another nix file like so to customize the global nixpkgs:
pkgs = import <nixpkgs> { config = (import ./config.nix); };
Try tracking the file interactions from configuration.nix and also try to understand all those flags at first, the PHP file is an "startup engine" of some kind I doesn't seem to have any possible configuration options it is just used as a run switch of some type and read rows 234-236(PHP) it says it needs config
also the http://nixos.org/nixos/manual/sec-configuration-syntax.html#sec-nix-syntax-summary is showing very clearly the possibilities. I say again I'm not into that engine but I think everything further to configure is done with the NixOS admin commands, it will be easier for me to help you if you explain what exactly you need done.
I'm following the instructions from BryanH's answer here: gettext() equivalent in Intl library? and trying to implement localization (translation) with php-intl, but I keep getting the same problem this person had: ResourceBundle returns NULL without any errors being raised
He mentions he created the dat files with a tool (which I cannot figure out how to work) while the person in the former answer simply appears to be using txt files with a .res extension.
How do I properly implement localization with php-intl and ResourceBundle, and what am I doing wrong?
The goal is to have various data files with different languages so I can do something similar to
$t = new Translator();
$t->setResource(new \ResourceBundle('es', 'locales_folder/'));
$t->echo("somestring"); // "el stringo"
..much like the person in the first answer had. Also, the aim is to have easily editable files, so I can give them to translators for fixes, updates, and so on. I realize I could easily do this with custom solution through a simple text file which gets parsed and saved into memcache on first request, where it then persists and gets served from without having to re-read the .dat files, but I'd rather take the suggested route here.
Edit: Just to get it out there - I implemented the same thing with gettext successfully and it was dead easy - save for one bug that persists across linux systems (http://www.php.net/manual/en/book.gettext.php#91187) - but I'd like to rely on the more modern and all-inclusive intl extension if possible.
I can provide a solution to your question on how to create and use .res files for the intl PHP extension, however I have no experience with speed and use in production systems, you will have to see for yourself if this can be a replacement for gettext.
In my opinion a great benefit of gettext are additional tools such as xgettext which can extract strings to be translated. Still, using resources might be more useful in your use-case.
To generate a .res file you need to use the program genrb which is bundled with ICU. (for example when installing ICU on OSX using brew install icu4c (see this tutorial) you can find the tool at /usr/local/Cellar/icu4c/*/bin/genrb (replace * with the version number))
Next you prepare a file for each locale. Let's do this for two languages in this example, German and Spanish.
$ cat de.txt
de {
hello { "Hallo" }
}
$ cat es.txt
es {
hello { "Hola" }
}
$ genrb *.txt
genrb number of files: 2
You now have 2 additional files de.res and es.res, which you can now access in PHP
<?php
foreach (array("de", "es") as $locale) {
$r = ResourceBundle::create($locale, __DIR__);
echo $r["hello"], "\n";
}
which will output
Hallo
Hola
So in essence, you can hand those *.txt files to your translaters and prepare them for PHP using genrb.
Finally, a small example for the class you were trying to write:
<?php
class Translator {
private $resourceBundle = null;
public function __construct(\ResourceBundle $r) {
$this->resourceBundle = $r;
}
public function __get($string) {
return $this->resourceBundle[$string];
}
}
$t = new Translator(new \ResourceBundle('es', __DIR__));
echo $t->hello;
I have started using v8js with php for a while now but the documentation is really thin.
One thing that is not explained is Extensions.
It is possible to registerExtension but it is not explained in detail how these behave or whats their purpose or benefits.
Can anyone provide a good description or link to a documentation that explains Extensions?
Thanks to everyone for taking time to read and answer :-)
Original Answer
My original answer indicated that the extension was called every time executeString was.
Corrected answer
An extension is a bit of code that is executed before the first executeString call for a given V8Js instance.
Extension can be global to all V8Js instances or local to a specific instance.
I have experimentally determined that this isn't always very reliable. If you frantically refresh a page, you may not always see the extension get run... This is probably why this is beta quality software.
Here are two examples that I whipped up
Global Extension Example
Code
V8Js::registerExtension('say_hi', 'print("hey from extension! "); var said_hi=true;', array(), true);
$v8 = new V8Js();
$v8->executeString('print("hello from regular code!")', 'test.php');
$v8->executeString('if (said_hi) { print(" extension already said hi"); }');
Output
hey from extension! hello from regular code! extension already said hi
Non-Global Example
Code
V8Js::registerExtension('say_hi', 'print("hey from non global extension! "); var said_hi=true;');
$v8 = new V8Js('PHP', array(), array('say_hi'));
$v8->executeString('print("hello from regular code!");', 'test.php');
$v8->executeString('if (said_hi) { print(" extension already said hi"); }');
Output
hey from non global extension! hello from regular code! extension already said hi
I am running my PHP code on my local computer,So ,I just want to know the PHP has any functions to get the local hard disk information.Such as the disk name , disk space,free space available .etc.
Thank you very much!!
Builtins:
disk_free_space()
disk_total_space()
If you need more, you can access local commands via system().
For disk usage, you'll also find different snippets on the net, e.g. this:
http://justynshull.com/2010/08/du2-php/, which uses shell_exec().
In addition, yes, it is possible to retrieve this information, because you can execute commands. There are a few PHP functions to retrieve information about the disk as well, check out the following links:
disk_total_space( $directory );
disk_free_space( $directory );
Retrieving the disk's name, however, needs to be done with a command. I've just booted Windows in VirtualBox and it seems the following would work:
if( preg_match( '~Volumenaam : (.*)~i', `fsutil fsinfo volumeinfo C:\\`, $matches ) ) {
echo $matches[1];
}
Volumenaam is Dutch for "Volumename". I only have the Dutch version of Windows, so you'd have to check what the actual string is.
Good luck.
There are two functions: disk_free_space() and disk_total_space().
Did you try searching the PHP manual before you asked here?
These two functions came up very quickly for me:
disk_total_space()
disk_free_space()
Further data such as the disc name may be trickier (you may need to use system() as per another answer here), but that should give you a start.
However, note that when PHP is running in a web site, it will have quite a lot of restrictions on what it can do; it's likely to be restricted to its local web folders for any disc access.
For the Disk Name you can use this function
function GetVolumeLabel($drive) {
// Try to grab the volume name
if (preg_match('#Volume in drive [a-zA-Z]* is (.*)\n#i', shell_exec('dir '.$drive.':'), $m)) {
$volname = ' ('.$m[1].')';
} else {
$volname = '';
}
return $volname;
}
echo GetVolumeLabel("c");
I want to display the list of shared drives connected to my system running Windows. Is there any tutorial for this?
I have tried the following code in PHP:
echo "<select id = 'drives'><option>Drives</option>";
for ($ii=66;$ii<92;$ii++)
{
$char = chr($ii);
if (opendir($char.":/"))
echo "<option>".$char."</option>";
}
echo "</select>";
You have to use the experimental Win32 API functions in PHP:
Register the API function GetDriveType using w32api-register-function.
After that you can call this function either by using w32api-invoke-function or by directly calling GetDriveType. It depends on your PHP version. (See the user contributed note at the bottom of the documentation of w32api-invoke-function!)
Check the return value if it is DRIVE_REMOTE. You can find the required parameters and the list of other return values at the MSDN documentation of GetDriveType.
You can enumerate Windows shared resources via PHP's COM API:
$wmi = new COM('WinMgmts:{impersonationLevel=impersonate}!root/cimv2');
$result = $wmi->ExecQuery('Select Path from Win32_Share where Type = 0');
foreach ($result as $share) {
echo $share->Path, PHP_EOL;
}
The output will list all shared folders on the machine. Type 0 is a disk drive.
See the MSDN documentation for Win32_Share for additional properties you can query.
Note: if you are looking for Mapped Network Drives, change the query to
Select ProviderName From Win32_LogicalDisk Where DriveType = 4
and change $share->Path to $share->ProviderName
See this Technet Article for details.
An alternative to using COM would be to use the wmic command:
exec('wmic Share where Type=0 get Path', $shares);
print_r($shares);
is equivalent to the first example above. For more details on WMIC, see
WMIC - Take Command-line Control over WMI and
Windows Management Instrumentation Command
This may help to do it under c#. http://www.codeproject.com/KB/IP/networkshares.aspx
I can't find any way to do it directly under php.
To use this with your php you may need make this as a dll and call it from php using the Win32 api functions.