Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.
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();

This also ensures you're not hardcoding a host name or port number in a class, much more configurable.

Adbot
ADBOT LOVES YOU

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

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

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.

Experto Crede posted:

This obviously means that every time the function is run that it will run the addserver() function.
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?

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');
?>

an skeleton
Apr 23, 2012

scowls @ u
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.

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
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:
<html>
    <body>
        <h1>Hello!</h1>
        <?php echo $user->name; ?>
    </body>
</html>
This is lovely 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));
    }
}
?>
But perhaps you don't want the system to throw a deadly exception when a missing user ID is given, perhaps instead it would show a different View, or the View should show its own error:
code:
<html>
    <body>
        <h1>Hello!</h1>
        <?php if $user instanceof User: ?>
	        <?php echo $user->name; ?>
	<?php else: ?>
		Invalid user.
	<?php endif; ?>
    </body>
</html>
The key aspect here is verifying the expected object. Until we've checked that $user is an instanceof User, it could be anything, and it's not safe to try and access its members.

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;
    }
}
?>
UserFormatter::formatFullName() type-hints the expected User class, and it's therefore safe to access the properties of the object that was hinted, because it'll only ever accept that object.
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',
    ],
];
?>
Yay! Array all the things!

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;
?>
What a god drat mess. And if I choose to refactor "userFilters" to "filters" I have to locate every occurrence of "userFilters" as plain text in my code and update it. What a nightmare!

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;
}
?>
A super basic pagination settings container class (basically a struct), we can always expect Pagination to contain a page and a 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;
    }
}
?>
Now whenever we get a page or a limit from the Pagination class, we know it'll be an integer within some pre-set ranges. We'll never get a string, and it'll never be -1, even if the user (or us!) tried to feed it invalid settings.

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.

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker
That's a Good Post. Gold stars all around.

an skeleton
Apr 23, 2012

scowls @ u

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++

bigmandan
Sep 11, 2001

lol internet
College Slice
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));
    }
}
?>
The findOrFail method will throw ModelNotFoundException if the record cannot be found. No need to explicitly check $id for type with this method. I think handling this exception as 404 page makes sense so you could add the following in app/start/global.php add:

php:
<?
App::error(function(Illuminate\Database\Eloquent\ModelNotFoundException $exception, $code)
{
    return Response::view('errors.404', array(), 404);
});
?>
and define the 'errors.404' template to show a 404 not found page.

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

revmoo
May 25, 2006

#basta
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?

Mogomra
Nov 5, 2005

simply having a wonderful time

revmoo posted:

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?

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.

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
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.

revmoo
May 25, 2006

#basta

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.

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.

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.

McGlockenshire
Dec 16, 2005

GOLLOCKS!
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?

revmoo
May 25, 2006

#basta
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.

DarkLotus
Sep 30, 2001

Lithium Hosting
Personal, Reseller & VPS Hosting
30-day no risk Free Trial &
90-days Money Back Guarantee!

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.

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.

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:
"autoload": {
        "classmap": [
            "app/Classes",
        ]
}
Edit:
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

revmoo
May 25, 2006

#basta
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

DarkLotus
Sep 30, 2001

Lithium Hosting
Personal, Reseller & VPS Hosting
30-day no risk Free Trial &
90-days Money Back Guarantee!

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"

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'

Sorry it wasn't a complete answer, I'm glad it got you pointed in the right direction though.

revmoo
May 25, 2006

#basta
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.

bigmandan
Sep 11, 2001

lol internet
College Slice

revmoo posted:

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.

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.

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.

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:
{
    "name": "My project"
    "repositories": [
        {
            "type": "package",
            "package": {
                "name": "jquery/jquery",
                "version": "1.10.2",
                "dist": {
                    "url": "http://code.jquery.com/jquery-1.10.2.js",
                    "type": "file"
                }
            }
        },
        {
            "type": "package",
            "package": {
                "name": "wordpress/wordpress",
                "type": "webroot",
                "version": "4.1.1",
                "source": {
                    "url": "git@github.com:WordPress/WordPress.git",
                    "type": "git",
                    "reference": "4.1.1"
                },
            }
        },
        {
            "type": "git",
            "url": "https://github.com/dave-newson/InfiniteFormBundle"
        }
    "require": {
        "wordpress/wordpress": "*",
        "jquery/jquery":  "1.10.*",
        "infinite-networks/form-bundle": "dev-polycollection-resize-entity"
    }
}
The first "repository" entry imports a specific file as named package "jquery/jquery" at version "1.10.2".
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.

revmoo
May 25, 2006

#basta
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.

McGlockenshire
Dec 16, 2005

GOLLOCKS!

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.

revmoo
May 25, 2006

#basta
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.

DarkLotus
Sep 30, 2001

Lithium Hosting
Personal, Reseller & VPS Hosting
30-day no risk Free Trial &
90-days Money Back Guarantee!

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.

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.

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?

revmoo
May 25, 2006

#basta
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.

DarkLotus
Sep 30, 2001

Lithium Hosting
Personal, Reseller & VPS Hosting
30-day no risk Free Trial &
90-days Money Back Guarantee!
Does this help at all?
http://serverfault.com/questions/566779/how-to-set-up-nginx-and-fastcgi-to-run-laravel-in-a-subfolder

revmoo
May 25, 2006

#basta
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.

Impotence
Nov 8, 2010
Lipstick Apathy
code:
    location /newsite {
            root /var/www/localhost/htdocs/newsite/public;
            try_files $uri $uri/ /index.php?$args;
    }

    location / {
            root /var/www/whatever;
            try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            include fastcgi_params;
    }

revmoo
May 25, 2006

#basta
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/

Impotence
Nov 8, 2010
Lipstick Apathy
What do you get with

code:
    location /newsite {
            root /var/www/localhost/htdocs;
            try_files $uri $uri/ /public/index.php?$args;
    }

revmoo
May 25, 2006

#basta

Biowarfare posted:

What do you get with

code:
    location /newsite {
            root /var/www/localhost/htdocs;
            try_files $uri $uri/ /public/index.php?$args;
    }

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.

DarkLotus
Sep 30, 2001

Lithium Hosting
Personal, Reseller & VPS Hosting
30-day no risk Free Trial &
90-days Money Back Guarantee!

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.

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.

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.

revmoo
May 25, 2006

#basta

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.

DarkLotus
Sep 30, 2001

Lithium Hosting
Personal, Reseller & VPS Hosting
30-day no risk Free Trial &
90-days Money Back Guarantee!

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.

I'll spend Monday morning on it and then move to a sub domain if I can't figure it out.

Honestly, Apache mpm event plays much nicer with php than nginx does. You might consider that for your php apps.

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.
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:
# nginx.conf

worker_processes 1;

events {
    worker_connections  1024;
}

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 0;
    client_max_body_size 64m;

    types_hash_max_size 2048;
    server_names_hash_bucket_size 96;

    server {
        listen 80;
        server_name localhost;

        location / {
            root html;
            index index.html index.htm;
        }

        error_page 404 /404.html;

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }
    }

    include vhost-app1.conf;
    include vhost-app2.conf;
    include vhost-app3.conf;
}
code:
# vhost-app1.conf

server {
    listen 80;
    server_name app1.staging.example.com;
    root /srv/http/apps/app1/current/web;

    access_log /srv/http/apps/app1/shared/log/http-access.log;
    error_log /srv/http/apps/app1/shared/log/http-error.log crit;

    location / {
        index  index.php;
        try_files $uri @rewriteapp;
    }

    # This may have to change for Laravel.
    location @rewriteapp {
        rewrite ^(.*)$ /app.php/$1 last;
    }

    location ~ ^/(app|app_dev|config)\.php(/|$) {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
All other configuration is stock nginx without any modifications. Hopefully that's enough to get going in the right direction.

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.

revmoo
May 25, 2006

#basta
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.

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.

revmoo posted:

That's a whole lot of effort when I can just create a /Classes directory and stick classes in there :)
This is not a good way to do things.

Pros
  • Its super quick to add a new library
  • Everything is contained within your repo/VCS. This is good for deploy-via-git with no ability to execute composer.
  • It's fast. Composer can be slow.

Cons
  • Committing lots of libraries can result in bloated VCS, especially if you frequently update your libs. This isn't fun to pull down, or walk history for.
  • You lose all connection with the version control and history from the third party libraries, which also means..
  • You don't know which branch or version you actually checked out. Maybe it was someones super secret special fork.
  • People get tempted to "fix an issue" with a library right there in your own VCS. Now you have to manually merge updates from the vendor and figure out what was changed and why - if you even notice - rather than just pulling them into your custom branch, then pull that branch to your project.

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.

revmoo
May 25, 2006

#basta
Yeahhhh not getting into that holy war.

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
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 :effort: 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.

Adbot
ADBOT LOVES YOU

bigmandan
Sep 11, 2001

lol internet
College Slice

v1nce posted:

...
[*]Committing lots of libraries can result in bloated VCS, especially if you frequently update your libs. This isn't fun to pull down, or walk history for.
...

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.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply