Two Codebases, composer in both causing issues with redeclaring functions - php

I have two codebases, one running as the primary web app, the other as the old code with legacy pages. Both codebases have their own composer installations, and that is where the problem occurs. When the first codebase has to call the second one, it is just a require secondApp. Both apps have, in requirements for other libraries, pake. The problem comes that Pake has a pake_autoloader function and the second one is noticing that the first already declared it, and throws an exception saying I cannot redeclare it. Both of these apps load Pake as a requirement for other libs. How do I get around the redeclaring issue?

Move both applications into one, and have only one composer.json file. Because by executing code of the "other" application, this really is only one big application.
A different idea would be to clearly seperate the two and only communicate via a defined interface, like making HTTP calls to the other application and using what's being returned.

Related

How to maintain code in two separate code bases for two different laravel projects?

So I am working on two different applications using laravel and both of them need a lot of the migrations, seeds, models, controllers, routes and so on similar to each other. In fact in most cases, they are absolutely same. What is the best solution to avoid redundancy in such a case.
The best solution I came up with was to extract a package and then use that package in both the applications but there are drawbacks. Every time I need to add a new feature which needs to be added to both of the laravel application, the package needs to updated. Once the package is updated, the main applications are updated. Sometimes small syntactical changes make me change something in the package and then update the packages again to see if it is working. But soon it becomes painful like this.
I have also tried using symlinks in composer file so that the package gets updated as I am working inside an application which uses them, but I still have to update the other application. Moreover, I still have to remove the symlinks before I push because the symlinks break in CI. They need the direct cloud URL for the repository.
Has anyone else gone into a similar problem with laravel and has an idea of how to resolve it? Or the best solution regarding the same.

How to prevent PHP namespace conflicts (pre-bundled packages)

Let's assume we have a PHP project with dependencies A and B each depending on PHP library X, but in a different version.
Usually, one would use a PHP dependency manager such as composer which would either resolve this conflict by including X in a version compatible to both A and B or display an error if the conflict cannot be resolved.
Now, many PHP applications allow their users to install plugins simply by uploading pre-bundled packages and extracting them to a specific plugin directory.
If A and B were such pre-bundled plugins and both would bring their own version of library X, we might run into problems since no dependency manager is available to select a compatible X for us or display an error in case there is none.
To prevent any such conflicts caused by the inability of PHP to have library X being loaded twice with different version into the same namespace, we could put A's X and B's X into different namespaces (which might be hard to do automatically as we would need a PHP parser for that...).
My question is:
How would you solve this problem? Can you recommend this approach or is there a better solution?
There is no solution without changing the code. If two versions of ´\Vendor\AnyClass´ do exist in the filesystem, and code is executed to use them both, either an error appears because redeclaring that class is not allowed, or because the expected class is incompatible. It will only work if the interface of the class is implemented the same, i.e. the two codes are compatible. The problem of compatibility is complicated if it isn't only that one class, but an entire tree of objects that may react badly to mixing classes from different versions, even though they offer a compatible interface.
Changing the namespace is changing the code. Who's responsible for that? I can think of some automatic code parser that would be able to add a specific namespace prefix for each plugin, but that task hasn't been done to my knowledge in PHP. The Java guys in my company made some remarks that such a problem has been solved there, but I have no details.
Also, it doubles your code base, and the duplicated code has to share only the one opcode cache you have.
I know that the core developers of Wordpress are still struggling with this problem. There are some coded suggestions of how to use Composer for dependency management (i.e. plugins and their dependencies), but I don't think they made enough progress for now.
Essentially you have two choices: 1. Create a code namespace prefixer, parse all the files belonging to a plugin (so the plugin author has to include his dependencies somehow), change the code, live with the code duplication, and see what awaits you when it comes to debugging. The downside is that no code outside of that plugin will be easily able to use the plugin code directly because that would mean to know the created prefix. 2. Implement some form of dependency management, preferably using Composer, and don't change the namespaces.
Update: I consulted my Java co-workers again, and they basically made the same statement about Java that I made about PHP: You cannot have two different versions of a class under the same class name, and there is no "magic" even for Java but renaming the class to a different namespace.

How can I reuse some laravel code?

I am developing web application using the laravel. I would like to 'package' some of the functions, which is re-usable. For example, I got a UserController, with database setup, and view, etc. The UserController is expected to re-use in most of the web development in the future, but some UserController may have different behavior, for example, some application's user may have a field rewardPoint, some may not. But they all have some similar behaviors, for example: register, login, forgetPassword, etc. So, can I package out a common UserController with all the basic database setup into one file or script to reduce the development work load? Thanks.
You've hit the nail on the head already - since your requirements are likely to change between projects you will struggle to create a single solution that works everywhere. You have a few options, including:
Copy the useful classes from your last project and update them to fit.
Create a package or bundle of base classes that include common and reusable code, then extend these into your project and modify the extensions as needed.
Attempt to create a "one solution for all" that you can drop in to all of your projects.
I would steer away from 3; it's likely to add the most bloat for the least gain. 1 is useful whilst you get used to the framework, especially if you tend not to revisit old projects; over time you will refine your code and develop patterns of work. Eventually you will probably end up doing 2; you can store these in git, use bundles or composer packages, and you can continue to improve them over time.

sharing libraries across web projects

I have 3 PHP projects using the CodeIgniter framework which share some exact same files such as models libraries and controllers. What's the best way I could share these files across without having to keep in sync and update the same files across?
In linux I thought of using dynamic links and extract these files to a central place but that kind of breaks our version control and would create portability issues.
Another way perhaps to use unison on these files across projects
I'm assuming that's a common problem, what are common approaches?
Separate them into a module, and use something like composer.
http://getcomposer.org/
Or just put them in a separate SCM.
One thing you can do:
Put all the shared code in libraries, helpers and models and place this in a separate folder. Then use:
$this->load->add_package_path('shared location');
Also take a look here: http://codeigniter.com/user_guide/libraries/loader.html , under application packages.
This works for most of the stuff, except controllers.
Use version control! In svn you can use externals, git has submodules or subtrees.
You don't want to use hardlinks, you'll run into weird issues like updating one project influences another project ("that I haven't touched in weeks").
The code can be in two physical places but shared under version control. There will always be only one authorative copy, namely the one in your version system. All physical copies are derivatives. It's important to see that you have control over when you update the code of a specific project, so a change at one point doesn't immediately break another project in case you made a mistake.
If you do want to catch these kinds of errors, set up a proper regression testing environment.
Sharing a development environment with another developer is also a big no. You don't want to have to wait till your colleague fixes a parse error that breaks the entire program. Each developer should have their own copy (checkout!) of a project and similarly each project should have their own copy (externaled) of shared code.
Seperate them into folders outside your project, then configure or include them in your projects.
Usually we will rewrite "autoloader" method for the project to find files in our new folders.

Managing several code bases that share overlapping function and classes

We have a website that has about 9 distinct code bases for various functions of it, that would run on different servers.
We use use SVN and scripts that copy the code from the repo to the staging servers for testing, so that's all automated. My issue is, there are functions and classes that exist in different codes bases, and they need to be kept in sync. So fixing a little bug in a function that gets a time offset, would require to me to go manually edit 5 other files in 5 other code bases. Once the code footprint grows, I wont even remember that this particular function may also exist in 5 other places.
What would be the best way to handle this type of stuff without just creating 2-3 massive "functions.php" files and cloning them to all code bases every single time?
I would suggest creating a new SVN repository(which contains the shared classes, files etc) and linking it as an external repository into your other project repositories that require shared code.
So for example you have numerous projects:
Project A
project B
etc and so forth.
Lets say both these projects share numerous classes.
I think one way to go forward would be to create a new SVN repository which includes the shared classes and then link this SVN repository into your existing repositories.
Advantages
Will allow you to have uniform & shared code deployed to all projects, without having to manually edit x amount of files each time your code repository is updated.
Additionally I would look into deploying your code using phing(A deployment tool) if you are not doing so already. it really is very good & useful. The link provided is a nice simple tutorial.

Categories