The crux of the issue is that I edit a code file and the change does not take effect until after I rebuild my entire environment. Weird thing is that I haven't been having this issue for months of development so far. I just decided to dust off this project and work on it this week and all of a sudden editing files no longer works (without a rebuild).
I don't even know where to begin to try and tackle this. Any advise helps, especially from people who have experience with Lando and Docker. Alright, so because I don't have any idea what's causing this, I'll just try and explain my whole set up and go from there:
I'm using Lando to run a container which is running PHP 7.3. When I SSH into the running container and execute my script php worker.php
my script runs no problems. Then if I edit it, say to add a var_dump('hello world!'), I get the expected output. However, if I edit an autoloaded class file, say MyClass.php, and add a var_dump there, nothing happens. In fact I have to completely rebuild the environment with lando rebuild
in order to get the var_dump to show up. Weird right?
Ok so here are some things I've tried:
- I've tried restarting Docker.
- I've tried restarting my computer.
- I've tried
lando destroy
andlando rebuild
to start fresh. - I've tried SSHing into the container and running
cat mylib/MyClass.php
and I see the added var_dump statement!! However when I runphp worker.php
the var_dump added to MyClass isn't there. How can it be present in the filesystem, yet absent during execution? This is really throwing me for a loop. - I've tried renaming MyClass.php to MyClass2.php and this fixes the issue ONCE. I.e. after it updates I then need to rename it again and again each time there is a change. This obviously isn't a real solution, but it's food for thought.
- I've tried manually loading classes using
include_once
. This works perfectly, edits take effect as soon as they happen. The problem is that I don't want to manually include all my files, I want to use the composer autoloader. I've been using it for a long time, I'd prefer to just fix whatever has suddenly gone wrong with it.
Ok lastly, some theories of mine:
- Something is obviously caching stuff but I have no idea what. I thought maybe it was something to do with the PHP Opcode caching, but I, to my knowledge, don't have php opcode caching enabled.
- Another theory is that maybe the filesystem mount isn't working. It is working, however, because when I edit worker.php the changes are instantly there each time. This would not be happening if there was no filesystem mount.
- One more theory is that either Docker is caching something somehow (I have no idea how), or maybe Lando is? I don't know Lando inside and out. Maybe it has some sort of caching scheme I'm not aware of.
- Last theory is that somehow autoloaded classes are cached by PHP itself or my composer or something like that. I also don't know how this is possible, but I'm not an expert on the inner workings of composer or php so if there is a code cache involved here somewhere I'm not aware of it.
So some things I know people might ask for: Dockerfile
FROM php:7.3-apache
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
libzip-dev \
libxml2-dev \
libssl-dev \
libc-client-dev \
libkrb5-dev \
&& docker-php-ext-configure imap --with-kerberos --with-imap-ssl \
&& CFLAGS="-I/usr/src/php" docker-php-ext-install zip mysqli pdo pdo_mysql xmlreader imap
RUN curl --silent --show-error https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
# Bake composer dependencies into the image for production
WORKDIR /app
COPY composer.json ./
COPY composer.lock ./
RUN export COMPOSER_ALLOW_SUPERUSER=1 && \
composer install --no-scripts --no-autoloader --no-dev
COPY . ./
RUN export COMPOSER_ALLOW_SUPERUSER=1 && \
composer dump-autoload --optimize && \
composer run-script post-install-cmd
COPY vhost.conf /etc/apache2/sites-available/000-default.conf
RUN chown -R www-data:www-data ./ && \
a2enmod rewrite
EXPOSE 80
.lando.yml
name: mysite
env_file:
- .env
proxy:
appserver:
- mysite.lndo.site
database:
- db.mysite.lndo.site
services:
appserver:
type: compose
services:
build: .
command: apache2-foreground
database:
type: mysql
portforward: 3306
creds:
---super secret---
composer.json
{
"name": "MySite/MySite",
"description": "Would work great if not for caching issues. :(",
"type": "project",
"require": {
"ext-json": "*",
"ext-imap": "*",
"doctrine/orm": "^2.6.2",
"doctrine/migrations": "^2.0",
"zbateson/mail-mime-parser": "^1.1",
"rct567/dom-query": "^0.7.0",
"sabre/xml": "^2.1",
"phpmailer/phpmailer": "^6.0"
},
"autoload": {
"psr-4": {
"MySite\\": "./lib"
}
}
}
Update:
I've found that by deleting vendor/symfony/console
and then running composer install
it seems to clear the cache. I wish I could figure it out from here, but the answer still eludes me. What does symfony console have to do with autoload caching code?? I have no idea.