Chapters
40 Chapters
|
4:39:58
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
16.
Flysystem: Streaming & Defensive Coding
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
This tutorial is built on Symfony 4 but works great in Symfony 5!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"aws/aws-sdk-php": "^3.87", // 3.87.10
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.1
"doctrine/doctrine-bundle": "^1.6.10", // 1.10.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.7.2
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.1
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-time-bundle": "^1.8", // 1.9.0
"league/flysystem-aws-s3-v3": "^1.0", // 1.0.22
"league/flysystem-cached-adapter": "^1.0", // 1.0.9
"liip/imagine-bundle": "^2.1", // 2.1.0
"nexylan/slack-bundle": "^2.0,<2.2.0", // v2.1.0
"oneup/flysystem-bundle": "^3.0", // 3.0.3
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.0
"sensio/framework-extra-bundle": "^5.1", // v5.2.4
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.2.3
"symfony/console": "^4.0", // v4.2.3
"symfony/flex": "^1.9", // v1.21.6
"symfony/form": "^4.0", // v4.2.3
"symfony/framework-bundle": "^4.0", // v4.2.3
"symfony/property-access": "4.2.*", // v4.2.3
"symfony/property-info": "4.2.*", // v4.2.3
"symfony/security-bundle": "^4.0", // v4.2.3
"symfony/serializer": "4.2.*", // v4.2.3
"symfony/twig-bundle": "^4.0", // v4.2.3
"symfony/validator": "^4.0", // v4.2.3
"symfony/web-server-bundle": "^4.0", // v4.2.3
"symfony/yaml": "^4.0", // v4.2.3
"twig/extensions": "^1.5" // v1.5.4
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.1.0
"easycorp/easy-log-handler": "^1.0.2", // v1.0.7
"fzaninotto/faker": "^1.7", // v1.8.0
"symfony/debug-bundle": "^3.3|^4.0", // v4.2.3
"symfony/dotenv": "^4.0", // v4.2.3
"symfony/maker-bundle": "^1.0", // v1.11.3
"symfony/monolog-bundle": "^3.0", // v3.3.1
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.2.3
"symfony/stopwatch": "4.2.*", // v4.2.3
"symfony/var-dumper": "^3.3|^4.0", // v4.2.3
"symfony/web-profiler-bundle": "4.2.*" // v4.2.3
}
}
13 Comments
Some chapters further in this course i recognized the following:
When a file gets deleted - e.g. through
$this->filesystem->delete(self::ARTICLE_IMAGE.'/'.$existingFilename);everything works fine... For the file itself. But the generated and cached thumbnails are still there.
Yeah i could clear the cache periodically (
./bin/console liip:imagine:cache:remove) but that feels nasty.Oh, nice the liip_imagine cache manager (
Liip\ImagineBundle\Imagine\Cache\CacheManager) can clear a single image (Docs) like that:$cacheManager->remove($path);But how do I get the needed path with our flysystem setup? I don't get it.
Or is there a other/better way at all?
Hey @Thanathan
Yes, you're right we didn't handle the cached image. As you already noticed there's a service to do that, you just need to send the same image path you send to the
Filesystemservice. But there's a gotcha, if you're using image filters, you need to specify them as well. Something like thisThat should do the trick. Cheers!
Hey @MolloKhan
Thanks for your prompt reply. 👍
I thought, I could omit the second parameter because of the documentations "Remove the cache for a specific image in all filter sets:
$cacheManager->remove($path);"But adding the second one doesn't hurt. 😉
My real problem is the value of
$imagePath. How can i get the correct path of the image when we're using "flysystem"? That's the part I'm struggling with. I checked the methods our instantiated file system provides, but couldn't find a hint. Isn't there some kind of "returnPathForFile($filename)" magic?I'm assuming you have a setup similar to what we have in this tutorial. You can see how Ryan deletes an image file here
https://symfonycasts.com/screencast/symfony-uploads/flysystem-defensive#codeblock-8abab61864
Basically, you grab the base path from somewhere, usually a constant or static method in a file, and append the name of the file that you stored in the
ArticleobjectI hope it helps. Cheers!
Hey! You've noticed about symfonycasts where you have sent error logs to Slack, can you please give the name or link of this tutorial? Thanks!
Hey Kirill,
I believe this is the video you're looking for https://symfonycasts.com/screencast/symfony4-fundamentals/logger-trait
By the way, at the top of the page, there's a search box where you can look for specific content just in this tutorial or through the whole site
Cheers!
Hello, since we need to use FlysystemOperator, the "write" and "delete" methods return "void". Because of this, we are unable to run these snippets:
We therefore cannot apply the "defensive" strategy demonstrated in the video. Is there an alternative?
I replaced it by :
What do you think ?
Hey Kiuega !
Ah yes - a difference between Flysystem v1 and v2. I need to see if we need some notes to the video related to this!
I think what you're referring to, specifically, is this: https://flysystem.thephpleague.com/v2/docs/what-is-new/#no-more-success-result-booleans
So, in v2, life is actually simpler. You don't need to code as defensively because the operation will work or it will NOT work and you will get an exception (without us needing to if it worked).
The code you put above, I think, is close - but we can simplify a bit more :).
A) For the
writeStream, there's no need to have a try/catch around this. Just call the method. Either it will work, or an exception will be thrown. So, it will have the same behavior that you see now (a different exception instance will be thrown, but that's fine).B) For the delete, you technically don't need the try/catch here either, unless you wanted to avoid failing (500 error) if the file is not found. If that's what you want to accomplish, then your code is perfect: you're catching just that one type of error. I don't think you need the
if ($existingFilename)part, but that's minor - and maybe there is more to your code that I'm not seeing.Cheers!
Hey Kiuega
Looks like you did a good investigation! The code you did is a good alternative! Sorry that you got difficulties with this part of course.
Cheers!
What is meant by "some streams close themselves"? At -7.49? Why are we closing something that already closes itself?
Hey Cameron,
> Why are we closing something that already closes itself?
Actually, it's the reverse... Ryan says:
> The "if" is needed because some Flysystem adapters close the stream by themselves.
So we need that "if" to find *those* steams that were not closed by themselves... and if they were not - we close it ourselves in that if :)
Makes sense for you now?
Cheers!
I have noticed that Exception for the stream write result is thrown before we check if stream was closed, does it matter? Maybe we should throw it after?
Hey Krzysztof K.
That's a good question. I'm not sure if after throwing an error the resource will be closed automatically, or if it may introduce any bugs. So, if you want to play defensively you may want to close it first and then check for errors.
Cheers!
"Houston: no signs of life"
Start the conversation!