|
Why not create the Memcache object outside of the function/class and pass it in so there's only one instance of it?php:<?php class CacheMe { private $memcached; public function __construct(Memcached $m) { $this->memcached = $m; } public function cacheMe() { // Do work. $this->memcached->cache($someData); } } $m = new Memcached(); $m->addServer('localhost', 11211); $c = new CacheMe($m); $c->cacheMe();
|
# ? May 7, 2015 20:07 |
|
|
# ? Jun 4, 2024 06:34 |
Experto Crede posted:Aside from it feeling a bit messy, will this cause problems? Is PHP smart enough to see that localhost is already a memcache server it's using? Or will I end up with a huge "pool" that consists of only one server repeated multiple times? Sounds like the answer is no, PHP is not smart enough to see that localhost is already in there: http://php.net/manual/en/memcached.addserver.php#110003
|
|
# ? May 7, 2015 20:22 |
|
Experto Crede posted:This obviously means that every time the function is run that it will run the addserver() function. fletcher posted:Sounds like the answer is no, PHP is not smart enough to see that localhost is already in there: http://php.net/manual/en/memcached.addserver.php#110003 The answer is to just beef up musclecoder's suggestion even further: php:<? class CacheMe { /** @var \Memcached */ private $memcached; public function __construct(\Memcached $m) { $this->memcached = $m; } public function set($k, $v, $exp = null) { // Do work. $this->memcached->add($k, $v, $exp); } public function get($k) { return $this->memcached->get($k); } public function setServers($servers = []) { $reconnect = false; $existingServers = $this->memcached->getServerList(); foreach($servers as $server) { $reconnect = (in_array($server, $existingServers) ? $reconnect : true); } if (count($existingServers) > count($servers)) { $reconnect = true; } if ($reconnect) { $this->changeServerList($servers); } } protected function changeServerList($servers) { $this->memcached->resetServerList(); $this->memcached->addServers($servers); } } $m = new \Memcached(); $c = new CacheMe($m); $c->setServers([ ['localhost', 11211, 10] ]); $c->set('blah', 'whatever'); ?>
|
# ? May 8, 2015 04:45 |
|
I've been working on a Laravel 4.2 project and I'm getting an unacceptable frequency of crashes related to bad data showing up on page-rendering-- such as a field or item missing and causing and "undefined index" or "trying to get property of non object" type errors. Basically, bad data in one way or another. Often I wish that it would just set these values to a null or blank string value instead of crashing but it seems like a nightmare to check every bit of data ever and set those values just in case. I'm used to more javascript-y projects where everything isn't so prone to crashing on bad/empty data. Does anyone have any advice for getting around this issue besides being super meticulous about maintaining the data-cleanliness of the project? BTW I'm a pretty novice web-dev and student so I may not be making the finest use of terminology, forgive me.
|
# ? May 12, 2015 23:20 |
|
This really depends what your code looks like (provide some examples maybe!), but generally speaking you do have to be careful about your data. Coming from the JavaScript world, I'd say you need to remember that doing any operation which would usually result in "undefined" from JavaScript will result in a fatal error in PHP. The rule is to consider everything an "unknown" and sanitize it for what you're expecting, before you try and use it. What do I mean by this? Well here's an example of some failure-prone code almost entirely from the Laravel docs: php:<? class UserController extends BaseController { public function showProfile($id) { $user = User::find($id); return View::make('user.profile', array('user' => $user)); } } ?> code:
Firstly, the incoming data isn't sanitized. If I call /user/show-profile/derpderpderp, it'll try to find "derpderpderp", which is retarded. Laravel can provide some sanitisation at the router level, but honestly I prefer to just play it safe when I go to use a piece of data like an ID. Secondly, the view requires that $user is always populated with a User object, because it blindly tries to access the name property. If I try to access an $id that doesn't exist then the User::find() method will return a null, and that'll break the view with a non-object error. How could this be less dumb? Well, we can fix the controller: php:<? class UserController extends BaseController { public function showProfile($id) { // Cast the input to an integer to make it safe for consumption $user = User::find((int) $id); // Ensure user is always found if (!$user instanceof User) { throw new \RuntimeException('Specified user could not be found.'); } return View::make('user.profile', array('user' => $user)); } } ?> code:
The other method of doing this is type hinting of expected objects. Say we have a dead simple class which does something with formatting the User's name: php:<? class UserFormatter { public static function formatFullName(User $user) { return $user->firstname . ' ' . $user->lastname; } } ?> Note that if you feed the method something else (eg. a different object), it'll throw a fatal error and call you mean names. If your code allows a variable to be more than one type of thing, you still need to be type checking somewhere before you pass it to other members. Now arrays are a different and more volatile beast. You can't type-check the structure of an array, and you've absolutely no idea what its structure might be, or what data the array might contain (int.. string.. object?). Arrays however are retarded simple to work with, which is why people throw them around like candy. php:<? $options = [ 'showUsers'=>true, 'userFilters'=> [ 'text' => 'jeff', ], ]; ?> Except don't, because when you want to access a property you often have to do poo poo like this: php:<? $textFilter = isset($options['userFilters']['text']) ? $options['userFilters']['text'] : null; ?> There's really no good way to save yourself from a complex array; you just have to use ternary statements like the above all over the shop, just to ensure the array contains what you're expecting. It only takes one typo to gently caress up the code. Alternatively, you can try to avoid arrays in most instances, and use objects for common structures instead: php:<? class Pagination { public $page; public $limit; } ?> But wait! we can also save ourselves a shedload of repeated code by using Getters and Setters on this class, and quietly sanitizing the data it handles: php:<? class Pagination { protected $page = 1; protected $limit = 10; public function getPage() { return $this->page; } public function getLimit() { return $this->limit; } public function setPage($page) { $page = (int) $page; $this->page = ($page < 1) ? 1 : $page; } public function setLimit($limit) { $limit = (int) $limit; $limit = ($limit > 100) ? 100 : $limit; $limit = ($limit < 1) ? 1 : $limit; $this->limit = $limit; } } ?> One of the biggest issues PHP developers seem to have is a fear of making new objects. I'm not saying you should object-orientate all of the things either, but you should definitely consider if the thing you're building would be better off as an object rather than a lumpy array. So uh.. yeah. Objects are nicer to work with than arrays. Type hint and sanitise your input. Don't try to access it if you haven't type checked what it is. isset() check your arrays values. Getters and Setters can help sanitise your poo poo. Don't put your dick in crazy.
|
# ? May 13, 2015 05:44 |
|
That's a Good Post. Gold stars all around.
|
# ? May 13, 2015 08:17 |
|
v1nce posted:lots of good stuff Thanks a ton! This is a bit to digest, so I'll be comparing with the code we are already using and thinking about how we can improve, but I'm sure that I couldn't have hoped for a better answer. Like the other dude said, Gold stars++
|
# ? May 13, 2015 16:42 |
|
In laravel 4 you could also do something like this:php:<? class UserController extends BaseController { public function showProfile($id) { $user = User::findOrFail($id); return View::make('user.profile', array('user' => $user)); } } ?> php:<? App::error(function(Illuminate\Database\Eloquent\ModelNotFoundException $exception, $code) { return Response::view('errors.404', array(), 404); }); ?> If you are looking at Laravel 5 in the future, things are handled differently bigmandan fucked around with this message at 19:35 on May 13, 2015 |
# ? May 13, 2015 19:30 |
|
I'm getting back into Laravel after a couple years off. I have a namespaces question: How do I use third-party libraries that use built-in PHP classes (SoapClient is a good example) without manually editing those third-party libs to insert 'use' statements into them? I need to include potentially hundreds of third-party classes and if I have to edit each PHP file manually to insert use statements it's going to be an absolute maintenance nightmare. Surely there's another way?
|
# ? May 14, 2015 12:20 |
|
revmoo posted:I'm getting back into Laravel after a couple years off. I have a namespaces question: My understanding is that you either edit each file manually to have a use statement, or edit each file manually to put a '\' in front of each use of a top level PHP class. If anyone knows a work around, I'd love to hear it too.
|
# ? May 14, 2015 13:43 |
|
Third party libs should still be a-ok to use built-in libraries, because they'd be looking for them on the global namespace. You don't need to prefix global classes with a \ unless you set a namespace in the same file, to my understanding. Composer can fill its autoloader map with non-namespaced classes, too and that might be your missing link. Obviously this isn't going to help you if you end up in a situation where two libraries set the same global class name.
|
# ? May 14, 2015 14:06 |
|
v1nce posted:Third party libs should still be a-ok to use built-in libraries, because they'd be looking for them on the global namespace. You don't need to prefix global classes with a \ unless you set a namespace in the same file, to my understanding. You have to declare a namespace afaik in order to get Laravel to autoload. I'm not really sure if there's a better way to work around the autoloading, perhaps somehow. I guess sticking these libs into composer packages might be a good way to go, but I have to balance the work involved in that vs editing my libs. Last time I built a composer package it was kind of a pain and had its own issues.
|
# ? May 14, 2015 14:40 |
|
Hold on a moment. Namespaces are scoped per file. Those external libraries are going to be in their own individual files, and therefore be in the global namespace if they don't declare one. You should never experience any namespace problems in those third party libraries, even referencing builtin classes. What's the actual problem you're having? Issues with the SOAP builtin being stupid about namespaced classes, where those SOAP class calls occur in third party code?
|
# ? May 14, 2015 16:34 |
|
I created a directory called app/Classes/ that contains third-party libs. In order to be able to autoload them and use them from a controller, I appended 'namespace App\Classes\ClassNameHere' (might be slightly off on this I'm not in front of my PC) in each class file. If there's another way of doing it, I'm all ears. BTW I tried just doing require_once() instead but that caused some extremely weird issues. It would say 'cannot redefine class', I assume due to some weirdly scoped autoloading happening behind the scenes.
|
# ? May 14, 2015 17:00 |
|
revmoo posted:I created a directory called app/Classes/ that contains third-party libs. In order to be able to autoload them and use them from a controller, I appended 'namespace App\Classes\ClassNameHere' (might be slightly off on this I'm not in front of my PC) in each class file. What about just adding that to your composer.json? If they are all classes, it should work fine. These aren't name spaced and this works great for me for any 3rd party libs I use or custom classes I write. code:
You can also add to the ClassLoader in app/start/global.php (laravel 4.2) or just require the specific library in that same file at the bottom. DarkLotus fucked around with this message at 17:41 on May 14, 2015 |
# ? May 14, 2015 17:38 |
|
That seems like really solid advice, but when I tried it I get the error "Class App\Classes\ApiClass\ClassName.php not found" That class actually does exist at that exact location, with that exact class/file name, and I'm calling 'new ClassName' in the controller, so it is obviously looking in the right place, but for some reason it doesn't see the file/class? If I remove the 'use' statement from the controller giving it the path to the class, it just says "App\Http\Controllers\App\Classes...etc not found" EDIT: According to this: https://laracasts.com/discuss/channels/general-discussion/l5-how-to-add-custom-php-classes-in-l5 the above advice won't work, you still need to add a namespace to your third-party libraries. EDIT2: Figured it out. I had to add 'use app\Classes\ApiClass\ClassName' to my controller, and then call it with 'new \ClassName', with the classmap 'app/Classes/ApiClass/ClassName.php' revmoo fucked around with this message at 19:36 on May 14, 2015 |
# ? May 14, 2015 19:02 |
|
revmoo posted:That seems like really solid advice, but when I tried it I get the error "Class App\Classes\ApiClass\ClassName.php not found" Sorry it wasn't a complete answer, I'm glad it got you pointed in the right direction though.
|
# ? May 14, 2015 20:37 |
|
Yes you definitely pointed me in the right direction, thanks. It's so nice to work in Laravel again, I've been stuck in 'legacy' code for the past two years.
|
# ? May 14, 2015 21:00 |
|
revmoo posted:Yes you definitely pointed me in the right direction, thanks. I just finished a 6 week stint of updating legacy (2002!) code, written by an ex-employee, to add a few "emergency" features. Pulling back the layers of mixed logic/presentation cthulhu spaghetti code was... unpleasant. After it was said and done I got the go ahead to do a complete rewrite at least, instead of supporting it for years to come.
|
# ? May 14, 2015 22:35 |
|
revmoo posted:I guess sticking these libs into composer packages might be a good way to go, but I have to balance the work involved in that vs editing my libs. Last time I built a composer package it was kind of a pain and had its own issues. You really don't have to do that. Composer can import non-composer packages. None of the projects I work on have any external source in the VCS - everything is managed by composer. code:
The second entry imports Wordpress, which is a github repo but not a composer package. The third entry makes composer use my fork of "infinite-networks/form-bundle", so I can drag in my branch of "dev-polycollection-resize-entity". My fork of form-bundle has its own composer.json from the original project, so it resolves to "infinite-networks/form-bundle". Composer resolves the repository list first, then downloads anything it couldn't resolve from the usual places. This is just an example I cobbled together, the syntax might not be perfect.
|
# ? May 15, 2015 00:05 |
|
That's a whole lot of effort when I can just create a /Classes directory and stick classes in there Anyway, I have another composer question. What's the best way to exclude the vendor .gitignore files permanently? For a number of reasons we cannot/will not run composer update on a live server so I need to commit /vendor. It's been a while since I did this and google is returning a bunch of different methods.
|
# ? May 15, 2015 13:17 |
|
revmoo posted:For a number of reasons we cannot/will not run composer update on a live server We're struggling with this same problem, only in our case some of the production servers don't actually have internet access and we're using composer to pull in PEAR things and it's really, really absurdly slow. Consider creating local repo clones and modifying the composer config to point there instead, or using Stasis instead of committing /vendor to your main repo. Another option may be changing your deploy methodology to create a separate local bundle of the contents of /vendor and use that instead. We're probably going to end up with this option.
|
# ? May 15, 2015 16:39 |
|
Well I've thoroughly stumped the guys in #nginx. Has anybody ever set up multiple PHP apps on a single server? I want to add my laravel app to a subdirectory and can't figure it out. I've got it mostly working but the config fails if I try to reach anything but /newapp/, for example /newapp/page actually loads the content from Laravel, but all the PHP environment vars are wrong, they're coming from the / PHP block rather than my /newapp/ PHP block.
|
# ? May 15, 2015 20:45 |
|
revmoo posted:Well I've thoroughly stumped the guys in #nginx. Has anybody ever set up multiple PHP apps on a single server? I want to add my laravel app to a subdirectory and can't figure it out. What's your config look like? Can you elaborate a bit more on your issue? What do you expect to happen and what is happening?
|
# ? May 15, 2015 21:05 |
|
Here's an abridged version: http://pastebin.com/EMPFALBV If I visit /newsite/ then everything works 100% perfectly. If I visit /newsite/page it loads the correct content from Laravel, but my PHP environment is all mangled as it's reading from the / PHP block rather than the /newsite PHP block. So on /newsite/ DOCUMENT_ROOT is correct but on /newsite/page, DOCUMENT_ROOT is wrong, it's the value for the / site.
|
# ? May 15, 2015 21:13 |
|
Does this help at all? http://serverfault.com/questions/566779/how-to-set-up-nginx-and-fastcgi-to-run-laravel-in-a-subfolder
|
# ? May 15, 2015 21:29 |
|
No not at all heh, I tried copy/pasting the relevant bits into my config and changed the parts necessary to make it work. PHP doesn't even serve with that setup, it just sends down the PHP file as plaintext.
|
# ? May 15, 2015 21:48 |
|
code:
|
# ? May 15, 2015 22:05 |
|
Doesn't work. I copied it verbatim changing only the dir paths to match my system. It serves out the / content if I visit /newsite/
|
# ? May 15, 2015 22:15 |
|
What do you get with code:
|
# ? May 15, 2015 22:18 |
|
Biowarfare posted:What do you get with Well /newsite would be /var/www/localhost/htdocs/newsite/public, however I tried it verbatim your way as well as using the correct path for /newsite. With your code verbatim I get 403 as it's trying to do a dir index. With correct path for /newsite/ I get 500 redirect cycle. If I add in the PHP block that would be necessary here for this to actually work I get a path that is wrong in the logs (/htdocs/newsite/public/newsite/public/index.php). Has nobody ever actually done this before? If there's a working config from someone whose actually done this I'd be more than happy to nuke my entire nginx config and start over with known-working code.
|
# ? May 15, 2015 22:34 |
|
revmoo posted:Well /newsite would be /var/www/localhost/htdocs/newsite/public, however I tried it verbatim your way as well as using the correct path for /newsite. Didn't read it through to the end... https://laracasts.com/discuss/channels/general-discussion/nginx-setup-for-subdirectory OR https://gist.github.com/tsolar/8d45ed05bcff8eb75404 Also, why do a subdirectory? A subdomain would be working already.
|
# ? May 16, 2015 00:20 |
|
DarkLotus posted:Also, why do a subdirectory? A subdomain would be working already. Starting to think this is the way to go. This is the first time since moving our platform to nginx that I've been disappointed with it. I hate getting defeated by a problem though. I'll spend Monday morning on it and then move to a sub domain if I can't figure it out.
|
# ? May 16, 2015 01:26 |
|
revmoo posted:Starting to think this is the way to go. This is the first time since moving our platform to nginx that I've been disappointed with it. I hate getting defeated by a problem though. Honestly, Apache mpm event plays much nicer with php than nginx does. You might consider that for your php apps.
|
# ? May 16, 2015 01:35 |
|
I would highly recommend going with sub-domains and use nginx with php-fpm (and opcache if available). Multiple PHP apps (whether Symfony or Laravel or whatever - shouldn't matter) with Nginx is a cinch - we use it on our staging server so we can have product1.example.com, product2.example.com, product3.example.com, etc. code:
code:
If you have a lot of apps, you can set a wildcard DNS *.staging.example.com to your server's IP and then let nginx route it out as well.
|
# ? May 16, 2015 03:39 |
|
Yeah I think subdomains is the way to go. BTW I find it interesting that everyone's rewrite/try_files for laravel seems to be different.
|
# ? May 16, 2015 14:11 |
|
revmoo posted:That's a whole lot of effort when I can just create a /Classes directory and stick classes in there Pros
Cons
Why you should care: Technical debt We'd love to code everything 100% perfect the first time through, but we only have so much time, effort and a certain number of fucks to give. This is why we take shortcuts and "just make it work", rather than making things fabulous on the first pass. This kind of thing is especially true for prototypes, and ranges from "Frameworks are hard to learn. I'll just make my own!" to "I'll put a string here rather than make a new const". Unfortunately for code with a long life, this leads to technical debt. Anything which isn't right will need to eventually be fixed later on. Those little tendrils of crap you can feel in your code, lurking in the back of your mind, that's the kind of thing I'm talking about. The more stuff you base on this technical debt, the worse it'll be when you eventually come to fix a problem it creates. Your framework, VCS and vendor libraries are not great places to introduce technical debt, because so much relies on them. Why you should care: Your fleeting mortality Time you spend diagnosing or solving problems with a bad implementation of something, especially when a "right way" exists but you aren't using it, is moments of your life you're literally giving to the sands of time. None of this poo poo is re-usable, apart from the tidbit that might have taken 8 hours to learn, which is you shouldn't be doing it that way in the first place. I know you probably have ~reasons~, but your reply was so broad I had to say something, lest someone else fall into the same trap with something sizable.
|
# ? May 18, 2015 02:30 |
|
Yeahhhh not getting into that holy war.
|
# ? May 18, 2015 12:54 |
|
There's really no war, that's why I gave a list of the pros and cons as I see them. My main point was to try and round out why we use Composer in the first place, just in case someone else reads your statement about and takes that as a reasonable argument against it. Like I said, I'm sure you've got your own reasons, and in some places its fine to do what you're doing. Just be aware of the pitfalls before you walk into them, so you can avoid the deepest ones.
|
# ? May 18, 2015 13:08 |
|
|
# ? Jun 4, 2024 06:34 |
|
v1nce posted:... This has burned me before. Keeping stuff separate is a good thing. We've been refactoring a lot of cruft where I'm at and one of the main goals is clean code and maintainability.
|
# ? May 19, 2015 15:00 |