I've done little web using namespaces. I have it in my computer and i'm about to moving it to free hosting that uses php 5.2. Syntax highlighter for php 5.2 interprets them as errors.
Are namespaces supported by php 5.2?
If not is there any way how to use them with little changes to existing code?
Namespaces are not supported prior to 5.3. There isn't really a way to adapt for them into 5.2 unfortunately.
Namespaces are only available as of 5.3
At least in the case of classes, you can use the class_exists function to check if a class has already been defined with a like name within the global namespace. Coupled with the __autoload() function, you can create one universal alias and have the system check for both classes named by the original name as well as the name with some kind of extra identifier prepended. I'll use "ns" as an example.
function __autoload($class){
try{
require_once('ns'.$class.'.php');
}catch(Exception $e){
echo 'The class is unavailable in pseudo-namespace as well as global';
}
}
Just make sure the require path points to wherever you keep your models. You could use a different folder instead of the alias as well.
This way, any duplicate classes can be put into files separate from the main execution that are only included if they don't exists in the global. Though this doesn't strictly fix the problem of having to physically rename the classes, it will allow you to put your definitions in different directories for versioning purposes etc.
Namespaces are available in PHP as of
PHP 5.3.0.
Source: http://www.php.net/manual/en/language.namespaces.rationale.php
http://www.php.net/manual/en/language.namespaces.rationale.php
Namespaces are available in PHP as of PHP 5.3.0.
Ive just come across this problem, ive developed an image upload script myself and added some third party code to aid image processing (cropping) but they use namespaces, works fine on my develoment machine, but when i uploaded to the live server i get a Parse error.
Luckily my host supports php 5.3 and 5.4, so ive asked them to change it to 5.3 for me, im hoping that will solve the problems im having, simply removing the namespaces made the script fail :(
Paul
Related
I'm slowly transitioning from PHP to Node.js and was trying to find something similar to composer dumpautoload. Thanks to PSR-4, it's easy to get access to any class in any file in PHP when using this command with simple use statements at the beginning of each file.
npm seems to do a great job managing packages and dependencies but having the same flexibility within your own project would avoid creating require statements that can easily break if a file changes path.
Example of what I would be looking for - 2 files in the same folder:
Some testClass.js (class file)
var testClass = {
sayHello: function () {
console.log('this is a test');
}
};
module.exports = testClass ;
Normally this is what you would put in another file index.js file:
var testClass = require('./testClass');
testClass.sayHello();
But imagine you could pre-index all your classes with some app or command (like PHP's composer dumpautoload and simply run this:
var testClass = require('testClass');
testClass.sayHello();
I couldn't find any solution that seems to achieve this.
Did I miss something?
Edit December 2020
Yarn2 did release a feature called Plug'n'Play which seems to mimic PHP's autoloader: https://yarnpkg.com/features/pnp
It is known to have issues with some packages but I have not tested it myself.
The short answer is: No
For more details, continue reading:
There are two major challenges around the current way require or import currently work:
Relative paths are hard to read and can become confusing when using files with the same name.
Developers must heavily rely on IDEs to refactor their code or to find where a file is when inside another file.
While PHP seems to have developed its own standard and is a bit in its own league, even if someone would develop an equivalent solution to achieve the same for Node.js/JavaScript, we would still need good IDE support. To get good IDE support, this type of change would either:
Need to be transparent and integrate to the way IDEs currently work.
Be a change that is driven by the community itself (either require or import changes that can support absolute paths)
There are several answers here (https://gist.github.com/branneman/8048520) and they all seem to break IDE support (I only tested with WebStorm):
Using aliases or prepending the path with variables: Breaks IDE support for autocomplete and renaming/refactoring.
Using NODE_PATH as root path: Breaks IDE support for autocomplete and renaming/refactoring.
Wrapping require to support /: Breaks IDE support when renaming/refactoring.
Creating a new custom method: Breaks IDE support for autocomplete.
Overall, given that IDE support take precedence over code readability, it looks like there is no good way to implement changes to the current dependency management using Node.js without having the community behind such change.
While not exactly like PHP, it is similar and very handy. I like this package. It is a bit older, but definitely in the right direction.
https://github.com/Specla/Autoloader
Then for database models if you are using Sequelize like I am it is pretty good.
https://github.com/boxsnake/sequelize-autoload
I was trying to build an application that will download some files from various ftp servers to a local directory. Later I would upload them to other ftp servers.
The application is built using Zend framework.
The thing is I can't find a class to handle ftp download/upload functions in Zend framework.
The only class available is Zend_File_Transfer which has the following comment:
Note: Limitation
The current implementation of Zend_File_Transfer is
limited to HTTP Post Uploads. Other adapters supporting downloads and
other protocols will be added in future releases. Unimplemented
methods will throw an exception. For now, you should use
Zend_File_Transfer_Adapter_Http directly. As soon as there are
multiple adapters available you can use a common interface.
I need to be able to do the following:
Upload multiple files.
Get a remote directory listing of all files.
Set validators
Set filters
Set paths
Rename files
Wrapper for downloads
Exceptions for various errors during operation.
Is there a solution to this problem in Zend framework? Could you recommend an alternative library for ftp operations ?
Thanks in advance
UPDATE:
I checked the PEAR package and unfortunately it's still in alpha
release. Moreover their functions return errors not exception once a
problem occur like download failure or remote path weren't found.
Unfortunately Skjb_Ftp isn't complete as many functions don't have an implementation.
Check out this php5 wrapper for the builtin FTP functions: https://github.com/dg/ftp-php it has some exception handling stuff you might be able to use.
This is a fully OOP php ftp library i build it in my self (hard working), its unit tested and it will works for your purposes perfectly. php-ftp-client
Here is great library for it: https://github.com/Nicolab/php-ftp-client
There is a proposal for Zend_Ftp that you might be able to use. Failing that, there is Skjb_Ftp.
I cannot vouch for the completeness or validity of either of these solutions, as I haven't used either, but it should be something to get you started. Some of the functionality you require is missing, but it shouldn't be too difficult to add it using the FTP functions.
Is there a tool to take a PHP file, with all its dependencies to other external PHP files, and create one, huge, final PHP file that includes them all?
Thanks
You don't really want to take a whole library and put it in a single file, because you end up loading a bunch of class definitions that might not even be needed by your script (i.e.: script A might need it, but not script B, however they end up loading it anyway).
PHP 5.3 (and a PECL extension for 5.2) introduced PHARs (PHP Archives), which works a little like JARs (Java equivalent):
$phar = new Phar('myLibrary.phar');
$phar->addFile('myClass.php');
Then you can do:
include_once('phar://myLibrary.phar/myClass.php');
I use it often and it is indeed very useful for quick software updates on client/production servers.
I've never heard of anything like that before, but maybe this could help... not really sure how it works http://webscripts.softpedia.com/script/PHP-Clases/Split-and-merge-files-19891.html
It is a new extension built-in PHP 5.3. You can read more about it here
http://www.php.net/manual/en/intro.phar.php
So I was reading about PHP namespaces, and I realized that in versions earlier than 5.3, if you write
namespace MyNamespace
you get a parse error.
Is there any way to avoid this i.e. make namespaces backwards-compatible, so the code doesn't simply crash?
Short Answer: No.
Longer Answer: (added to capture useful information from other deleted answers). The new Syntax will cause parse errors in PHP, so you can't use a customer error handler to catch errors generated in versions < 5.3. In theory you could write a pre-processor the scans and/or does a lex/parse on the source and then write something back out that would be PHP 5.2 compatible, but that creates more problems than it solves.
Perhaps you could query the version of PHP being used and call eval if it's high enough. I don't know if that will work though.
Actually, I think it's possible, but I don't believe it's worth it. The idea would be to create a custom default stream wrapper, which will parse PHP files according to the new grammar and make the appropriate changes to the syntax so that it will be valid PHP < 5.3.
The wrapper would have to replace class names such as Foo\Bar\Baz with Foo_Bar_Baz. Currently I'm not sure if there's something that would render this impossible.
Anyway, I don't believe it's worth the effort. Upgrade to PHP 5.3.
Oh, that means that the wrapper code should be compatible with PHP < 5.3.
I know this is a very old question, but I needed to make a couple of instructions with namespaces backward compatible with a very old PHP installation (5.2).
What I finally did to avoid parse errors was:
if(version_compare(PHP_VERSION, '5.3.0') >= 0) {
include("file_with_namespaces_code.php");
}
else{
echo("put php 5.2 code here");
}
I am running Symfony (1.2.9) with PHP Version 5.2.11 on Windows XP.
I have APC installed (Version 3.0.19)
I can run PHP script to prove that apc is working correctly (works). However, when I try to use APC calls in a symfony action, I get this error (in the apache error.log file):
[apc-error] Cannot redeclare class sfconfig
Which promptly crashes Apache.
I tried using the Symfony sfAPCCache wrapper, and then directly calling the apc_* functions - the result is the same. Does anyone know why this is happening ?
Checkout these threads:
http://pecl.php.net/bugs/bug.php?id=16860
http://old.nabble.com/APC-under-WinXP-crashes-td25872662.html
Today this error happened to me, too, and I became aware of why it can happen (among possible other reasons).
APC correctly identifies every class by a fully qualified name, which includes the classes namespace. Unfortunately you can end up referring to the same class with various names.
For example:
I had a wrong "use" statement in my code, importing a non-namespaced class as if it had been inside a namespace.
The class, say "MyClass" was in namespace "\", meaning that its correct and fully qualified name was "\MyClass".
At some point the class was referred to by its unqualified name "MyClass", and got autoloaded. In another file I (wrongly) referred to the class with a namespace prefix in a use statement, say "use \SomeNamespace\MyClass;". Consequently the class was (again) passed to my global __autoload() method, but with a different name. To make it worse, the autoload method was smart enough to find the class anyway.
Instantly, my script stopped working and all that happened was APC writing "[apc-error] Cannot redeclare class ..." into the Apache Web Server error.log. My pages were no longer available.
This is not an APC bug whatsoever, but simply correct behaviour.
In my case it helped to temporarily disable APC (so that my script would be run regardless of the conflict), and hook an echo statement into my __autoload function producing a list of the parameters passed. The class loaded with a wrong name would show up quickly, and I could fix it and reenable APC.
Hope this helps someone.
Ive had this error before unrelated to APC and it always helped to not only run the cache:clear but also to check and make sure all files were deleted from the cache dir.
I was living the same situation on my development windows
system with php 5.2.11 and several apc versions. Same
situation as described, with stat=0 everything works, but
when I set stat=1, apache crashes with error "cannot
redeclare class [some class]". The code is working on a
different windows system, beside it is live on a heavily
loaded linux production server for months. I'm %100 sure
there is no bug related to apc. It started on my machine
after I reinstalled my OS.
I spent some time commenting out some class includes and
realized that it works with some include files but not with
specific ones. I checked my code there is no noticeable
difference on the class differences.
Then I saved all of my include files with adding some
additional whitespaces with Zend Studio's editor. It looks
stupid I know but it works!!! I'm working on the project
with several people and using svn and everybody uses
different text editors like notepad++, editplus etc...
However I couldn't reproduce the error by trying save the
file with some different editors with different configs like
ansi, utf8 with/without byte-mark ordering etc. But I'm sure
my problem is something related to file format (encoding,
pc/unix mode). I'd like to reproduce the error and want to
give more detailed info but I tried my solution on another
project with same problem, it works either.
I hope I could give another perspective to the issue.
What solved this for me was making sure my requires had the same path.
For example, the error I got was:
[apc-error] Cannot redeclare class someClass
In file A I had the following:
require_once '/path/to/someClass.php';
In file B which resides in the same directory as someClass.php I had the following:
require_once 'someClass.php';
I believe that APC caching didn't understand they were the same file because the path was specified for one and not the other.