Jump to content
MakeWebGames

john.

Members
  • Posts

    63
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by john.

  1. Let me know if come to a point where shameful offers are acceptable. I need a design for my engine. =)
  2. +1 http://digitalocean.com/ Awesome prices, awesome performance.
  3. john.

    PDO Problem

    Well, there you have the problem. PDO and MySQLI isn't the same thing. You need to create a PDO instance, i.e   new PDO($dsn, $username, $password);   Your code in the first example is also invalid: $query = $db->prepare("INSERT INTO `owners` (`username`, `password`, `email`) VALUES (?,?,?,?)"); $password = password_hash($_POST['password'], PASSWORD_BCRYPT); $query->execute(array($username, $password, $email));   Remove one of the question marks.
  4. Ah, yes. I updated with text clarifying the ways you could choose a fetching style in the Read section!   Thank you! Hopefully it will, my goal was to let this tutorial serve as introductory as well as some sort of reference for people going to PDO.   Thanks!
  5. Ah.... yes... how silly of me :)
  6. Thank you, let me know if you have any issues following along.   Thanks for the input. I didn't know about filter_input, until now. I'll have a look at it later.   Thank you! :)
  7. Today we'll cover the basics of PDO, PHP Data Objects which is a modern alternative to the now depreceated MySQL API. (mysql_connect, mysql_query, you know!) It provides some new features such as prepared statements, a well-designed object-oriented interface, multiple support for different database drivers, object mapping, stored procedores and it's performance is fast. To follow along with the tutorial, create a database and use the following sql diagram, we'll use utf8 as our encoding.   CREATE SCHEMA `booky` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ; CREATE TABLE `booky`.`books` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(128) NULL, `author` VARCHAR(150) NULL, PRIMARY KEY (`id`));   Let's start off by making a connection: A PDO object is constructed with 4 parameters where three of them are optional, the dns, username, password and options. The second and third one is quite obvious the username and password to your database server, but what about dns and options? dns or Data Source Name as it stands for contains the information required to make a connection. Typically with the old MySQL extension you would provide a host, and the database name, well if you didn't figure it out already that's what you do in the dns. (Or the location to a file database like Sqlite). How about some code to illustrate?   <?php $db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $db = new PDO("sqlite:/path/database.db");   So we create a database hantle (the $db object), we provide the Data Source Name that contains the database type (in first example mysql), and then some database specific stuff, like only the path to the db when sqlite and host and name on mysql. To ensure we have the same collation (character encoding) throughout our application it is considered good practice to set the charset attribute in the DNS, like this:   $db = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $pass);   As we mentioned earlier PDO has many different drivers, you may check out the ones you have by doing:   <?php print_r(PDO::getAvailableDrivers());   or looking in your php.ini file. To close a connection you simply set the variable containing the object to null, i.e.   $db = null;   Error Handling If you ever remember how bad error handling with the old MySql extension was, I'll brief you to say it's simple and great in PDO. You probably did   or die(mysql_error());   No more of that. In PDO we have three different error modes, as they are called. These error modes can be set through setting attributes to the object we created when connecting. The method is called setAttribute . Error Strategies: PDO::ERRMODE_SILENT (default) The errors can be read via errorCode() and errorInfo methods(). No errors will be displayed or outputted. PDO::ERRMODE_WARNING The same functionality as above, but also generates a traditional E_WARNING message. PDO::ERRMODE_EXCEPTION Exceptions. Throws PDOException that you can catch and act accordingly.   <?php try { $db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { if ($debugging) { echo $e; //__toString() calls and outputs some nice debugging info } //In production: ****! Send a SMS to engineer now... }   We use setAttribute to set the PDO::ATTR_ERRMODE (which is a constant) to whet ever error mode we like. Here's a list if you want to know more attributes that can be set. http://se1.php.net/manual/en/pdo.setattribute.php   -- CRUD -- Create - Read - Update - Delete Create Let's create a book (by inserting data to the books table).   //Data, provided by a User, from a form, etc. // A object $db is assumed to have been created earlier $name = 'In Paradise: A Novel'; $author = 'Peter Matthiessen'; $stmt = $db->prepare('INSERT INTO `books`(name, author) VALUES(?, ?)'); $stmt->execute(array($name, $author)); //Assuming we have 0 entries before... echo $db->lastInsertId(); // "1"   The example above uses prepared statements to safely insert a book entry. Forget about escaping ahead, prepared statements does this for you. The other benefit is that the query only need to be prepared once and can then later be executed multiple times with the same or different parameters. So you could do the following:   //Data, provided by a User, from a form, etc. // A object $db is assumed to have been created earlier $name = 'In Paradise: A Novel'; $author = 'Peter Matthiessen'; $stmt = $db->prepare('INSERT INTO `books`(name, author) VALUES(?, ?)'); $stmt->execute(array($name, $author)); $name = 'Prayer'; $author = 'Philip Kerr'; $stmt->execute(array($name, $author)); echo $db->lastInsertId(); // "2"   The prepare() methods creates a PDOStatement, which described by php.net is "Represents a prepared statement and, after the statement is executed, an associated result set." So an additonal object is created, the PDOStatement has the parsed (prepared) query and then after the query has been executed, (execute()) we can retrieve a result set in various ways and so forth. We could also do fancy stuff as counting columns and rows. More about that soon. Did you notice the ?, these are called unnamed parameters. The items in the array within execute() must match the number of ? (parameters) in the query. When using many parameters in a query, it may simplify to instead use named parameters:   //Data, provided by a User, from a form, etc. // A object $db is assumed to have been created earlier $name = 'In Paradise: A Novel'; $author = 'Peter Matthiessen'; $stmt = $db->prepare('INSERT INTO `books`(name, author) VALUES(:name, :author)'); $stmt->execute(array( ':name' => $name, ':author' => $author, ));   Use named or unnamed parameters as you like, I prefer to use named parameters for queries with many parameters and unnamed parameters for those with few. Beware that you cannot mix the both, so use either. Read Now when we have data in our table, let's have a look at it. We have looked at prepared statements, but let's assume we have a static query with no parameters, in this scenario we can use the query() method instead to retrieve data.   $sql = 'SELECT name, author FROM books'; foreach ($db->query($sql) as $row) { echo $row['name'] . "\t"; echo $row['author'] . "\t"; }   As you can see the the $row is an associtave array, but this depends on how you have configured your PDO object. Let's use a different fetching style.   <?php $sql = 'SELECT name, author FROM books'; $stmt = $db->query($sql); $stmt->setFetchMode(PDO::FETCH_NUM); while ($row = $stmt->fetch()) { echo $row[0] . "\t" . $row[1] . "\n"; }   A quoted list from php.net about fetching styles.   There are two ways you can choose fetching style, one is using setFetchMode() as in the code example above, but you could also pass as parameter to the fetch methods which fetching style you like, like the example just below. Lets have a final example with using a prepared statement instead, you remember that once a PDOStatement has been executed I said that you can fetch data, this is how:   <?php $stmt = $db->prepare("SELECT name, author FROM books"); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); print_r($result);   This will contain one row. If you fetch again, you'll have the next one. So, if you haven't already figured it out a loop is at rescue.   <?php $stmt = $db->prepare("SELECT name, author FROM books"); $stmt->execute(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { print_r($row); }   Instead of looping, you could use fetchAll() to store the result in an array.   <?php $stmt = $db->prepare("SELECT name, author FROM books"); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_OBJ); print_r($rows);   Remember that you must have made a database object before executing all the code above, the examples are simplified, but assumes that you have a $db object created. Update Now when we have some data, let's make some updates.   <?php $stmt = $dbh->prepare("UPDATE books SET author = ? WHERE id = 1"); $stmt->execute(array('John Doe')); echo $stmt->rowCount(); //1   Simple enough. rowCount() is a method that allows you to count the rows that been affected by DELETE, UPDATE or INSERT.   <?php $stmt = $dbh->prepare("UPDATE books SET author = ?"); $stmt->execute(array('John Doe')); echo $stmt->rowCount(); //2   DELETE Finally we have DELETE. It is as simple as UPDATE.   <?php $stmt = $dbh->prepare("DELETE FROM books"); $stmt->execute(); echo $stmt->rowCount(); //2   Searching Just add the wild cards!   $name = 'John'; $stmt = $db->prepare("SELECT name FROM books WHERE name LIKE ?"); $stmt->execute(array($name . '%')); while ($row = $stmt->fetch()) { echo $row['name']; //John Doe }   bindParam and bindValue Instead of passing all the data as an array you could use bindParam or bindValue to bind a parameter in a prepared statement. The first argument of both the methods is the parameter name, and the second is the variable. The third one is a constant that represents types, and is usually used with stored procedures. Have a look at http://www.php.net/manual/en/pdo.constants.php But what is the different between the two? The difference is that bindParam() binds the variable as reference, which means that the variable can be modified before the PDOStatement is executed, mean while bindValue() binds the variables value and if variable is changed, the bindValue isn't. Here is a good example I found, as I barely use these methods myself.   $sex = 'male'; $s = $dbh->prepare('SELECT name FROM students WHERE sex = :sex'); $s->bindParam(':sex', $sex); // use bindParam to bind the variable $sex = 'female'; $s->execute(); // executed with WHERE sex = 'female' $sex = 'male'; $s = $dbh->prepare('SELECT name FROM students WHERE sex = :sex'); $s->bindValue(':sex', $sex); // use bindValue to bind the variable's value $sex = 'female'; $s->execute(); // executed with WHERE sex = 'male'   PDO::quote — Quotes a string for use in a query. quote() is the fallback method if you by some reason need to escape a string to a query. To make sure this doesn't fail you have to set the charset properly, either on server level or at the database connection (depends entirely on your driver, on MySQL it works fine.)   /* Simple string */ $string = 'Nice'; print "Unquoted string: $string\n"; print "Quoted string: " . $conn->quote($string) . "\n"; //Results: //Unquoted string: Nice //Quoted string: 'Nice' Remember in almost any case prepared statements are much better to do when dealing with user input being entered to a database, don't rely on escaping but use prepared statements. Transactions Transactions allows you to execute multiple queries before actually comitting them. It makes sense if a query failed, you would want to rollback some other query that relies on the latter.   <?php /* Begin a transaction, turning off autocommit */ $dbh->beginTransaction(); /* Change the database schema and data */ $sth = $dbh->exec("DROP TABLE fruit"); $sth = $dbh->exec("UPDATE dessert SET name = 'hamburger'"); /* Recognize mistake and roll back changes */ $dbh->rollBack(); /* Database connection is now back in autocommit mode */ ?>   The methods are pretty self-explanatory, and so easy to accomplish in PDO, right? In old extension you would have to manually execute a query that sets to transaction mode. Conclusion As you can see working with PDO is quite simple, instead of escaping data, use a prepared statement to ensure a secure query. You have a lot of different fetching styles that you can use, it's all about preferences mostly but sometimes there can be useful to specifically say: I need the data in following format. Transactions just became much easier and so did iterating data through. If you have any questions, feel free to ask them. Any comments and feedback is highly appreciated. And yes, some of the examples are inspired/borrowed from the manual, but modified to be put in context.
  8. Hey! When I edited my topic and added some additional information, the and [sql] tags were removed. When I got the original post back, I had to "Go to advanced" to make sure the code snippets, images stayed. I use latest Firefox.
  9. Today we'll make a simple user registration script. We'll cover the basics of PDO and Form validation. We'll also look at current best practices for hashing passwords. It's assumed that you have basic/intermediate knowledge of PHP, as well as that you have a web server/web host with at least PHP 5.3.7 installed and know how to create a MySQL database (or execute SQL code to a db server). If you need a web server and PHP (locally), look for WampServer if you're on Windows, MAMP if you use Mac, LAMP for Linux etc. These packages comes with every tool you need to follow through the tutorial, but there are plenty tutorials on how to install and setup these things. If you don't know PDO; read a tutorial: http://makewebgames.io/showthread.php/44586-How-to-PDO-in-One-Two-Three!?p=301700#post301700 Let's start by the SQL and execute the following in your favorite database management tool (I use MySQL Workbench). CREATE SCHEMA `pandora` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ; CREATE TABLE `pandora`.`users` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `username` VARCHAR(20) NULL, `password` VARCHAR(60) NULL, `email` VARCHAR(100) NULL, `created` TIMESTAMP NULL, `confirmed` TINYINT(1) NULL DEFAULT 0, PRIMARY KEY (`id`), INDEX `username` (`username` ASC)); If you already have a database, you could remove the first line and on third line replace "pandora" your database name (just make sure the collation is utf8) and then execute that SQL instead, in anyhow you've accomplished the task when you have a database and a table called users. The table is fairly simple, we have two columns for user identification username and password, an email address if they wish to reset their password, the created is a TIMESTAMP which contains the TIMESTAMP when the User was created. Finally we have a boolean (a TINYINT(1) is often referred as a boolean) that checks if the user is confirmed or not (meaning that the email has been verified). Now when we have the database set up, let's get started with the coding. Firstly we need to make a database connection. We'll use PDO, PHP Data Objects that is one of the extensions that replaces the now deprecated (mysql_) API. (mysql_connect, mysql_query, you know?) Create a file on your web server named config.php. <?php $config = array( 'db' => array( 'dsn' => 'mysql:host=localhost;dbname=pandora;charset=utf8', 'username' => 'root', 'password' => 'password', 'options' => array(), ), ); $db = new PDO( $config['db']['dsn'], $config['db']['username'], $config['db']['password'], $config['db']['options'] ); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); Line 3-10 is our configuration array, here we would add an configuration items that later can be added throughout $config['item']; As you can see I use a multidimensional array which is cleaner and easier to work with, every database configuration I would place in the ['db'], and then to be accessed like: $config['db']['item']; This part is not really essential of the tutorial, you could have 4 variables instead, however a lean way of storing configuring statically. Line 5 is the fairly interesting line here. This is called the dns. We tell PDO that we soon create that we want to use the MySQL driver, (PDO supports many drivers!), we want to use the database "pandora", the host (localhost, locally) and finally charset utf8. Almost like the ordinary mysql_connect, right? Line 6-7 should be obvious, your db user and db password. Leave line 8 for now. Line 13-18 is where we create the $db (PDO object). We pass the config parameters, DNS, username, password and options. And voila, we have our db object work with. Unlike mysql_ API, PDO uses objects. PDO has different error modes, on the final line we specifically say we want PDO to throw Exceptions if something fuzzy going on, like PDO cannot find the database etc. Now when we have the database connection we can continue by creating the register.php file. <?php require 'config.php'; function validate_registration($db) { } if (isset($_POST['register'])) { } ?> <!DOCTYPE html> <html> <head> <title></title> </head> <body> <form method="post" action="register.php"> <input type="text" name="username" value=""> <input type="password" name="password" value=""> <input type="email" name="email" value=""> <input type="submit" name="register" value="Register"> </form> </body> </html> Here we have the very basics we need to get started. Firstly, we include the config.php file we just created earlier. And then we create a function, here we'll validate the form data when the form is processed. Line 11 basically looks like "Hey, have the Register button been pressed (aka form submitted) - if so... let's process the form here...". So, imagine the form has been submitted. What do we need to check to make sure the submitted data is valid? We need to know: That a username, password and email has been entered. That the username is not already taken. That the email is valid. We also want: That the username/password has a minimum length. That the username follows a pattern (say only alphanumerical) Let's add the following code (after function validate_registration($db) {) $errors = array(); // Required fields $fields = array('username', 'password', 'email'); foreach ($fields as $field) { if (empty($_POST[$field])) { $errors[] = 'Field ' . $field . ' is required'; } } //If we already have errors, let's interrupt the validation process if ( $errors ) { return $errors; } if (strlen($_POST['username']) < 3) { $errors[] = 'Username is too short'; } else if (preg_match('/[^a-z0-9_-]+/i', $_POST['username'])) { $errors[] = 'The username must only contain alphanumerical, dashes and underscores'; } if (strlen($_POST['password']) < 6) { $errors[] = 'The password is too short'; } //Make sure the email is valid if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) === false) { $errors[] = 'The email is not valid'; } if ( $errors ) { return $errors; } $_POST['email'] = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL); //Make sure the username is not already taken $stmt = $db->prepare("SELECT `id` FROM `users` WHERE `username` = ?"); $stmt->execute(array($_POST['username'])); if ($stmt->fetch()) { $errors[] = 'The username is already taken'; } return $errors; "HOLY ****. That was a lot of code." - Hey, hey, just relax now. Take a big breath and let's go it through. Firstly we create a $errors = array(); this array contains any error that may occur, we'll also use this array to check during the validation process wherever to continue or not. Like it makes no sense to make a database connection and check if the username exists or not, if the username in say is already invalid. Line 3-10 makes sure that the fields that I put in the array (username, password, email) are required and if these aren't present, we tell so. Line 12-15 makes the first check. If the errors array contains some values, the validation has already failed. So let's interrupt the process by returning the errors array. Line 19 checks that the username matches a pattern, the username must only contain alphanumerical, underscores and dashes - if not, well, we have an error here sir! $stmt = $db->prepare("SELECT `id` FROM `users` WHERE `username` = ?"); $stmt->execute(array($_POST['username'])); if ($stmt->fetch()) { $errors[] = 'The username is already taken'; } Here(s) some more PDO magic. We use a prepared statements (which prevents SQL injection). So first we tell, hey PDO prepare this SQL for us. This creates a PDOStatement that is stored in the $stmt variable. On line two we say, hey PDOStatement execute this and use this data for the first parameter. (Notice the array?, if we want more parameters, we simply add the data in the array!) On the fourth line we try to the fetch the executed statement, if it succeeds a user is found and the test has failed. Finally in the validation we return the $errors array(). If it's empty, the validation has succeeded! Soon, we're going to use a function called password_hash that isn't available as of PHP 5.5. If you have this version or above, you're fine and if not you'll have to follow along and download a backward compatibility library named password_compact which allows you use these functions as of PHP 5.3.7 (hence the requirement for this tutorial). So if you have PHP 5.5 > you can skip this paragraph and if not, follow along. Let's go to https://github.com/ircmaxell/password_compat, click on "lib" folder and then the password.php file. You'll see a button called "Raw" click on it and the file will be opened as raw. Right click and save the file as password.php on your web root. Now open your config.php file and put require 'password'.php'; below the db object creation. Done! Now when we have the validation figured out, let's continue with the registration. The logic is as, if the registration validation passes, let's insert the User in to the database, and if not store some error messages and refresh the page. Let's add session_start(); in the top of our config.php file. Within: if (isset($_POST['register'])) { and } (duh!) Let's add: $errors = validate_registration($db); //If we have errors, let's store them in a session and refresh the page... if ($errors) { $_SESSION['register_errors'] = $errors; header("Location: register.php"); exit; } //Hash the password with bcrypt $password = password_hash($_POST['password'], PASSWORD_BCRYPT); $stmt = $db->prepare("INSERT INTO `users`(`username`, `password`, `email`, `created`) VALUES(?, ?, ?, NOW())"); $stmt->execute(array($_POST['username'], $password, $_POST['email'])); //We can safely assume the user has been registered, if not an exception would be thrown and handled elsewhere... header("Location: registered.php"); exit; First we call the validation function and stores the result in the $errors, either an empty array or some horrifying errors. If there are errors, we'll store them in a session, and then we refresh the page (Remember; we just did a POST request, so we're not suppose to show any data in this state, but instead redirect back to register.php, so the request is GET instead, this pattern is known as GET/POST/GET). If we have no errors, we has the password with the password_hash function. We'll use the PASSWORD_BCRYPT as a second parameter. bcrypt is a best practice when storing passwords in data storages, this is also the reason why the password in the database table is varchar 60, a hashed passwords contains 60 characters long. Line 13-14 we use yet again another prepared statements, we have 3 fields that requires three parameters (these parameters are known as unnamed parameters). We use prepared statement because it prevents SQL injection. If you remember what I told about the execute array, you now see it in action. We have 3 parameters (three ? in the SQL query) hence we have three data variables to pass to the execute. Because we earlier in config.php set ERRMODE to Exceptions we can safely assume that the registration will pass and if not the error should be handled somewhere else. ( A global exception handler). So let's redirect the registered.php. Now again, we redirected the User back to register.php if the registration failed. So let's see what we can do about that. Below the ending } of isset($_POST['reg...] add the following: if (isset($_SESSION['register_errors'])) { $errors = $_SESSION['register_errors']; unset($_SESSION['register_errors']); } And in our HTML, below the <body> let's add <?php if (isset($errors)): ?> <ul> <?php foreach ($errors as $error): ?> <li><?php echo $error; ?></li> <?php endforeach; ?> </ul> <?php endif; ?> Now we're ready to try out our result. Here is mine: What now? Well, once you have a User registered the next step would be to be able to login and have member protected pages. I won't be able to cover it all here, but If you have absolutely no idea where to start, here's some ideas (and maybe I'll write another tutorial about this, if you like too!) Use Sessions to store the id of a user, when logged in. ($_SESSION['user_id'] = $row['id']) Use password_verify (http://se2.php.net/manual/en/function.password-verify.php) to check if the hashed password in the database matches the password a user entered when logging in. Use prepared statements When logging in, you will check if the username exists and retrieve the User (with his password) and then you'll do the above 2 steps. Validation as through as registration is not needed when logging a User in, you only need to check if the user exists and then if the username and password is correct you'll log in the user, no need for checking length of username etc. What can you do next on this registration page? Add some styling for the forms Add more fields for the registration itself, like firstname, lastname etc. Put the HTML code somewhere else (separate PHP and HTML!) That's it! Comments, questions, feedback - please!
  10. john.

    Securing $_POST

    Personally I would use a Validation library to make sure the data is valid (according to my rules). Filtering/Escaping the User(s) data is just common sense. If you enter data in database, you would use prepared statement. When outputting data you escape it properly with i.e. htmlspecialchars.
  11. It was higher than expected, however we didn't put that much effort early on balancing and playing on the economy, we are still in Beta and it's a work in progress for the final release (and restart). Playing with the number is always fun; but it's hard to get it right imo.
  12. We don't have any attributes related to making a certain task easier, expect a general attribute making every y task easier. And the bots already making these tasks randomly, not sure If it's in some pattern as of yet though.   Barely had the game started before we had 2-3 players admitted they botted. :P   Logging and tracking what Users does is on our ToDo, and from there we hope to be able to implement an automatic system that can help us.
  13. We have a game where User can perform different tasks, giving them money and such. People are cheating. And we know about it. But we don't know about how we should prevent it. People are using Macros to perform these requests (simulating), the better ones have started to implement different intervals to perform these different tasks, which eliminates our suspiciousness at the logging files. Some Captcha randomly is currently what we are thinking about trying... I would like your ideas on though. How do you make it a pain for the cheaters?
  14. Read about a guy who posted that he had been hacked a couple of years ago, apparently he had executed that command himself, after seeing an administrator on the forums having in its signature saying something differently about the commands real purpose. Social engineering, lol!
  15. I have to say it's not bad. I would probably remove the arrow above the Login box, it just looks silly in my opinion, I would also make the size of the "Login" heading a bit smaller. I would make the gun in the logo smaller and be in proportion with rest of the logo. Additional padding below the Sign up button. Making the container (the design itself) a bit wider width, it seems too small right now. Also, to make up for the lack of art in the design itself which is good because of stylistically pure it is, I would consider adding some more esthetically background that adds up the art.
  16. I have to agree with the earlier posts, it was easy. The documentation was pedagogical and well written too which helped a lot.
  17. The other developer actually had a droplet on http://digitalocean.com/ and we decided to try it out - with success. I will see If I can find the spec, it was a shared host. However we are much happy with the new performance for now, so now we'll focus on bug fixes and features!
  18. Edit: We updated our host. The game is now running 7,5 x faster and has good ms. :D
  19. Yes, all scripts have been minified. The queries are optimized and cached as far as my knowledge goes. Our conclusion is that a better host would definitely help and we're considering a new one. How important is it that the VPS/Droplet etc. is in the same country area?
  20. We just launched a web game yesterday on a pretty bad shared host. We improved the speed a lot by implementing cache, however it leans towards getting a VPS or Cloud Server instead. How do you maintain your game to be at good performance? Better servers? Improve code? What should we focus on first? How many players does your game have? What kind of hosting do you use? How do you maintain your project to keep good performance?
  21. Some messy structure has been uploaded, however the core lays almost as it should be. I will be cleaning up tomorrow, but if anyone feel like checking it out, I've pushed the repository linked in the first post. (Yes, I am aware of some security threats, and I'll deal with them as well tomorrow). Yeah, I am to tired to finish the last hour, haha. Anyway. I think I got a solid start.
  22. I haven't decided yet whet ever how to handle the business logic, however the presentation (views) and controller is separated. A URL points to a modules command, a command loads appropriate data and then renders template, is how it works so far.
  23. Well, let me expand a bit. Obviously, a full-featured game engine is impossible to get done within 5 hours (unless you're awesome), so we could scratch that right away. However, getting the architecture of a modular engine is possible, but again this would be a very early alpha. We'll see how it goes, I am used working with crazy deadlines.
  24. Agreed. Eloquent is awesome and a brief to work with. Occasionally you may have some complex queries that can be tricky to solve with Eloquent, but usually not a issue. I've tried RedBean as well, it's certainly comforting to use when developing prototypes, have never used it in a released project or in work however.
  25. Current game I am developing is built with Laravel, however pretty much all code is reusable so I guess I have my game engine right there for my next project.
×
×
  • Create New...