Jasmine Tutorial: Unit Testing Promises In Services

Leave a comment Standard
jasmine

So recently I’ve been doing a lot of Angular unit tests with Jasmine and Grunt. I have to say, testing promises is extremely frustrating and most of the examples I found out there either 1) didn’t work or 2) wouldn’t allow you to test content in a then block if you had multiple chained promises, or if you had a promise being called from and returned from another service. After many hours of frustrating trial and errors I found a solution I’m happy with so I want to share.

Let’s assume this is your controller:

'use strict';

angular.module('myModule').controller('myCtrl', ['$scope', 'api',
function ($scope, $api) {

  $scope.data = null;
  $scope.message = null;

  /**
  * Load some data from the API service
  * @return boolean
  **/
  $scope.loadData = function () {

    var config = {
      method: 'GET',
      url: 'http://api.domain.com/someRESTfulEndpoint',
      headers: {'Content-Type': 'application/json'},
      data: null
    };

    return $api.load(config).then(function (request) {
      if (request) {
        $scope.message = 'Your data was successfully loaded';
        $scope.data = request.response;
        return true;
      } else {
        $scope.message = 'The API service failed';
      }
      return false;
    });
  };
}]);

And here is the service making your API calls:

'use strict';

angular.module('myModule').service('api', ['$rootScope', '$http',
  function ($rootScope, $http) {

    /**
    * Makes the $http request given the proper configuration options
    * @param Object configruation for the $http request
    * @return Object $http promise that resolves to request payload or error
    **/
    this.load = function (options) {
      return $http({
        method: options.method || 'GET',
        url: options.url || 'http://api.domain.com/someDefaultEndpoint',
        headers: options.headers || null,
        data: options.data || null
      }).then(
        function (request) {
          //we got a response back, return just the API payload data
          if (request.status === 200 && request.data) {
            return request.data;
          } else {
            return {
              results: false,
              message: 'API request error',
              response: request
           };
         }
       }
     );
   };
}]);

Finally, this is your working unit tests:

'use strict';

describe('testing myModule', function () {

  beforeEach(module('myModule'));

  var $controller, $rootScope, $scope, $api, $httpBackend, $q;

  beforeEach(
    inject(function (_$controller_, _$rootScope_, api, _$httpBackend_, _$q_) {
      $controller = _$controller_;
      $rootScope = _$rootScope_;
      $httpBackend = _$httpBackend_;
      $q = _$q_;
      $api = api;
      $scope = $rootScope.$new();

      $httpBackend.when('GET').respond('test http GET call');
      $httpBackend.when('POST').respond('test http POST call');

      $controller('myCtrl', {
        $scope: $scope,
        $api: $api
      });
    })
  );

  it('has a $scope.loadData() function', function() {

    var testConfig = {
      method: 'POST',
      url: 'http://api.domain.com/endpoint',
      data: { some: 'data'}
    };

    var fakeData = { data: 'is fake' };

    //we spy on the API service and also return a fake promise call
    spyOn($api, 'load').and.callFake(
      function() {
        var deferred = $q.defer();
        deferred.resolve({result: true, response: fakeData});
        return deferred.promise;
      });
    });

    $scope.loadData(testConfig); //call the function we're testing in the controller
    $scope.$apply(); //we have to call this so Angular will try and resolve the promise
    expect($api.load.calls.count()).toEqual(1); //make sure it's called the api service
    expect($scope.message).toEqual('Your data was successfully loaded');
    expect($scope.data).toEqual(fakeData);
  });

  it('returns an error if the API fails', function() {

    var testConfig = {
      method: 'POST',
      url: 'http://api.domain.com/endpoint',
      data: { some: 'data'}
    };

    spyOn($api, 'load').and.callFake(
      function() {
        var deferred = $q.defer();
        deferred.resolve({
        result: false,
        message: 'api error'
      });
      return deferred.promise;
    });

    $scope.loadData(testConfig);
    $scope.$apply();
    expect($scope.message).toEqual('api error');
    expect($api.load.calls.count()).toEqual(1);
  });
});

 

Sample Angular Website

Leave a comment Standard
AngularJS

So I’ve seen a lot of people using AngularJS but I see very few examples of a website made using it. That’s why I decided to post an example website to give you an idea of what a full website looks like using AngularJS. It has samples of some of the things you’ll commonly find in a website made entirely with Angular:

  •  Navigation & Routing
  • Providers & Directives
  • Controllers & Config Blocks
  • Data Calculations
  • Filtering

Sorry if you’re looking for Angular 2.0, this was made with Angular 1.5.8. View, fork and/or edit the files on Plunker!

PHP Tutorial: Cookies vs Sessions

Leave a comment Standard
1421823729zxptl

If you’re interested in making any kind of web based application then learning how to use sessions and cookies is a must. Many people don’t understand how these work and how they different from each other, and why you would choose to use one versus the other. So put on your thinking caps and let’s get started.

What is a Cookie?

A cookie is a data file that’s written to your browser’s localStorage with data you want to keep track of for a user. So what’s localStorage? The best real world analogy I can give you is to think about it like a 3 ring binder that you can add, update and remove files from. In this example a cookie would be a piece of paper in your 3 ring binder.

How Do Cookies Work?

When you navigate around the Internet your browser is constantly sending and receiving information from the websites you want to access. These are called HTTP headers. HTTP headers contain important information about the requests and responses being sent back and forth from a browser to a server. When someone has an active cookie from your website in their browser’s localStorage it automatically passed in the HTTP headers to the site of origin in the $_COOKIE variable of PHP. Since headers have to be sent before any output setting a cookie must always go at the top of your file.

How do I Create a Cookie?

<?php
$name = "myCookie";
$value = "hello world!";
$expires = time() + 60 * 60 * 24; //1 day
$path = "/";
$domain = "yourwebsite.com";
$secure = 0; //0 for false, 1 for true
$httponly = 0; //0 for false, 1 for true

//let's tell the browser to create our cookie
setcookie($name, $value, $expires, $path, $domain, $secure, $httponly);

//let's make a cookie array too
setcookie("cookieArray[0]", "A");
setcookie("cookieArray[1]", "B");
setcookie("cookieArray[2]", "C");

//you must refresh the page before your new cookies are visible
echo "refresh the page to see your cookies: " . $_COOKIE['myCookie'];

//this will loop through and display your array cookies
foreach ($_COOKIE['cookieArray'] as $key => $value)
{
 echo "<br/>array cookie $key => $value";
}
?>

In this first example we’ve created a cookie called myCookie that stores the value of hello world! In order to see something printed on the screen you must refresh the page. This is because the HTTP headers must be sent from the server to your browser and then from your browser back to the server before they show up in the $_COOKIE variable.

Expires is an optional value that tells the browser how long to keep our cookie before it deletes it. By using the current time() and then adding on an extra 24 hours our cookie will only stick around for a day before the browser deletes it. So in this example if your cookie is created at today at 12noon EST it will expire tomorrow at 12noon EST. When your cookie is expired you’ll have to create a new one if you want to store your $value again.

Next we’ve set a path for our cookie. This is also an optional field and will default to / if you don’t give it a value. This tells the browser where this cookie will be available. So let’s say your website is http://yourwebsite.com and you only want this cookie to be available when you’re inside the http://yourwebsite.com/users/ section or your website. If that were the case we’d change the path to /users/ and then our cookie will only be accessible when we’re in the users directory. When we leave the path at / it means our cookie is available on any part of the domain we’ve given it.

The domain of your cookie is optional. If you don’t provide a domain for your cookie it may default to your current domain name. You can also set your domain name to a subdomain. So for instance, if we had a subdomain of http://users.yourwebsite.com we would set our domain to users.yourwebsite.com then our cookie would only be available when we’re inside our users subdomain.

The secure section of the cookie is optional and should only be set to true if you’re using https.

The httponly is optional and tells newer browser to only make your cookie accessible in the HTTP header. Not all browsers support this functionality, however it has been added to help prevent against cross site scripting (XSS) attacks.

How do I Access Cookie Values?

<?php
//this shows you a single cookie
echo $_COOKIE['myCookie'];

//this shows you all available cookies
print_r($_COOKIE);
?>

Once you have a cookie set you can access it by using the $_COOKIE variable in PHP and then pass it the name of the cookie you want to access or you can use a print_r() call to print all available cookies.

How do I Delete a Cookie?

<?php
//unset the single cookie
unset($_COOKIE['myCookie']);

//unset the array cookies
unset($_COOKIE['cookieArray']);

//update the cookie's expiration date to sometime in the past
setcookie("myCookie", false, time()-1);
setcookie("cookieArray[0]", false, time()-1);
setcookie("cookieArray[1]", false, time()-1);
setcookie("cookieArray[2]", false, time()-1);
?>

Sometimes you want to remove a cookie. There are two different ways to do this. The first is to unset() the cookie and the second is to update the expiration date to a time in the past which will force your browser to remove it. Just like when we set a cookie, you must refresh the page before you will see that your cookie has been removed.

How do I Edit a Cookie?

<?php
//to edit a single cookie value
setcookie("myCookie", "My new value");

//to edit a cookie array
setcookie("cookieArray[0]", "one");
setcookie("cookieArray[1]", "two");
setcookie("cookieArray[2]", "three");
?>

As long as the cookie exists all you need to do is set the cookie with the same name and give it a different value. You won’t see that the values in your cookie have changed until you refresh the page since cookies are sent in an HTTP header.

Cookie Trouble Shooting

  • If you’re having trouble setting a cookie and you’re getting a headers already sent error then you have some kind of output (text, spaces, html, images, etc) that are being displayed to the screen before you’re calling your setcookie() function.
  • Once you’ve added, edited or deleted a cookie you must refresh the page before you can see that your changes have taken place. This is because cookies are sent in HTTP headers.
  • Cookies must be deleted with the exact same parameters as they were set with.
  • Cookie arrays are stored as one file for each index in the array. For this reason large arrays are not recommended. If you need to store lots of data in a cookie it’s more useful to use a single cooke and concatenate the values with implode() then retrieve the data  using explode().
  • If one of the values in your cookie resolves to a false your cookie will be deleted. For this reason you shouldn’t use true/false booleans but instead use 0 and 1.
  • It is not recommended to serialize your cookie values as this can cause security holes.
  • If the user’s browser has cookies disabled or will not allow cookies to be stored then you won’t be able to create a cookie in their localStorage. This problem gave rise to the creation of sessions.

What Is a Session?

Sessions are the best solution for short term storage of data and dealing with user’s browsers that don’t allow the creation of cookies. Sessions will attempt to create a cookie and if the attempt fails will instead propagate via the URL. However a session will only persist over the duration of a user’s visit on your website. Once the user leaves your site the cookie (if one was created) is deleted so there is no persistent information retained about the user in the browser’s localStorage once they’ve left your website.

How do I Create a Session?

<?php
//you have to start the sessions before you can use them
session_start();

//set a single session value
$_SESSION['mySession'] = "hello world!";

//set an array in a session
$_SESSION['myArray'] = new array('A', 'B', 'C');

//set an object in a session
$_SESSION['myObject'] = new myObject();
//this tells php your done making changes to the session
session_write_close();

//session values are immediately available
echo $_SESSION['mySession'];
print_r($_SESSION['myArray']);
print_r($_SESSION['myObject']);
?>

All sessions must be started with the session_start() call unless you have them set to auto start in your php.ini file. Usually this isn’t the case with most hosting providers. In addition session_start can take parameters to configure the length of the session and the storage location, etc, however most hosting providers don’t let you change these settings so I won’t cover them here.

Sessions are sent via HTTP headers just like cookies are (when PHP tries to create a temporary cookie), however since they can persist without cookies the data is immediately accessible once it has been initialized. This means you won’t have to refresh the page to access the data you’ve stored in them.

How do I Access Session Values?

<?php
session_start();

echo $_SESSION['mySession'];
print_r($_SESSION['myArray']);
print_r($_SESSION['myObject']);
?>

Unlike cookies where you have to refresh the page before you can access them, session values are immediately available once they’ve been set. All you have to do is start the sessions (unless sessions have been set to auto start) and then look for the name of the session you want to access.

How do I Delete a Session?

<?php
session_start();

//remove a single session values
unset($_SESSION['mySession']);
unset($_SESSION['myArray']);
unset($_SESSION['myObject']);

//alternative way to remove a session values
$_SESSION['mySession'] = false;
$_SESSION['myArray'] = null;
$_SESSION['myObject'] = '';
//this tells php your done making changes to the session
session_write_close();

//remove all session values
session_destroy();
?>

The best way to remove a session is to unset it, however you can also set the value to falsey or call session_destroy() to remove all session values.

How do I Edit Session Values?

<?php
//you have to start the sessions before you can use them
session_start();

//edit a single session value
$_SESSION['mySession'] = "new value!";

//edit an array in a session
$_SESSION['myArray'] = new array('one', 'two', 'three');

//edit an object in a session
$_SESSION['myObject'] = new myNewObject();

//this tells php your done making changes to the session
session_write_close();

//session value changes are immediately available
echo $_SESSION['mySession'];
print_r($_SESSION['myArray']);
print_r($_SESSION['myObject']);
?>

You can edit session values the same way you set them initially.

Session Troubleshooting

  • If you’re having trouble getting a session started and you’re getting  headers already sent errors then you have some kind of output (text, spaces, html, images, etc) that are being displayed to the screen before you’re calling your start_session() function.
  • Sessions will only last for the duration of a user’s visit or for the session_expiration time that’s set in the php.ini file. You can learn more about session configuration values in the PHP manual.
  • Make sure you’re not doing an unset($_SESSION) as this will make it impossible to register any new values in the $_SESSION.
  •  You can’t use reference variables in sessions.
  • If register_globals are enabled they will overwrite variables with the same $_SESSION name. For instance if you have a session named mySession and register_globals is enabled and you create a $mySession variable it will overwrite the $_SESSION[‘mySession’] value with whatever you’ve assigned to $mySession.
  • If you’re having a problem changing values in your session make sure you’re calling session_write_close() after you’ve made changes to session values. This is especially important if you’re doing a lot of asynchronous ajax calls.

Should I Use a Session or a Cookie?

The best way to answer this question is do you need data on a user to persist once they’ve closed their browser? Sessions will only last for the duration of a user’s visit on your website, they will disappear as soon as the user has closed all windows and tabs that they have open for your website. Cookies, on the other hand, will remain on a user’s computer until the user removes them from their browser or they expire.

Pros & Cons of Sessions vs Cookies

Type Pros Cons
Sessions Excellent for short term data storage

Can access immediately after initialization

Will create a temporary cookie if cookies are enabled/supported, otherwise propagated on the URL

Can be used for authentication

Only last for the duration of the user’s visit

Susceptible to XSS attacks

Cookies Excellent for long term storage of data

Can be used for authentication

Must be enabled/supported on the browser

Must refresh the page before you can access cookie data

Susceptible to XSS attacks

Why Making A Game Takes the Fun Out of It (and how to fix this)

Comments 4 Standard
angry-woman

I see it all the time, people coming into forums and online communities for games and game developers asking how to make a game or how to get their ultra cool idea that everyone will love and has never been done before off the ground and make it a tangible reality. Let’s get things straight, we love games because they’re fun and entertaining. It drives our creative vision and imagination and offers an escape from the mundane and the boring reality that is our lives. This passion, this drive to express ourselves and have fun is often what leads people to try their hand at making their own games. Many will start this journey but very few will finish it and even fewer will finish it with a successful and positive outcome (and let’s face it, money in your pockets). So why does this happen? Why do so many people start down this path of learning and creativity and adventure for fun that ends up leaving them broken, frustrated and depressed? The reality is that games are a lot of work and the very nature of making a game isn’t even a little bit fun. In many ways it’s the exact opposite of what we’re trying to achieve. So how does this happen and what can we do to fix it? Let’s break it down from the point of view of an Indie game developer whose a one man shop (or small shop) trying to make a game.

Lack of skills

You want to make a game but you’ve never programmed before, you don’t know anything about what’s required to make the type of game you want to create and even if you have those things covered you may not have all the skills you need to make it happen. Just because you can program doesn’t mean you can draw or compose artwork or market your finished product if you ever get that far. As an indie game developer you really have to be a jack of all trades. Think about trying to build a house if you’ve never built a house before. What happens if you only know how to frame the house but not how to do plumbing and electrical and tile work and all the other things that are required to finish the house? You end up with just the shell of a house that is lacking in so many ways you can hardly call it a house. This is one of the biggest problems I see with indie game devs — they lack the skills to accomplish what they’ve set out to do and they’re not prepared to outsource when they need to, which brings me to my next point.

Budget constraints

Making games is inherently expensive. Even if you create your own game framework and develop your own models/artwork, sounds and music you still have to — at a minimum — invest in a computer and dedicate hundreds of hours towards the development of your game. Those hours add up and while you’re developing your game you’re not earning a living that you need to support yourself and/or your family. Yes, that’s right, you still need to eat and buy necessities and support yourself and/or your family which is why even if you do have the funds outsource some of the work you lack the skills for you’re still fighting a losing battle towards my next point.

Time constraints and distractions

Supporting yourself and your family means that you’ll still need a full time job even as you chase the ethereal dream of creating your own game. Your time is precious and what little of it you have left after your regular day job has to be split between your other financial and personal commitments. Your kids need their parents and your house and car need to be maintained and you’ll struggle to find the proper work/life balance amidst all of the chaos that you juggle on a daily basis without adding the complexities of your game into the mix.

Technical problems, bugs, new frameworks and advances

So even if you can overcome all these odds so far you’ll still find yourself stuck hitting roadblocks as your game progresses. Technical problems you didn’t predict or forsee early on (and how could you, you’re still just learning yourself) end up being the bane of your game’s existence. Now you have to go back and re-write and re-factor and debug until you’re so frustrated you could pull all of your hair out and go bald. New frameworks and technological advances will make your second guess yourself or roll back to square one because you really do want to upgrade your SDK and add in the new dynamic system and better bump map texturing because who doesn’t want their game to be using the newest, latest and greatest technology available? No one wants to play a game that doesn’t have the same bells and whistles that their competition does because they took the the extra time/budget/testing cycle hits to go with the greater tech.

Slow progress and scope creep

Ultimately these things combined will drag your game down. What may have started off well and progressing quickly has suddenly slowed to a snail’s pace. Things suddenly feel like they’re never getting done or you have so many issues on your plate that it feels like there’s never an end in sight. Your game has hit a standstill and isn’t advancing like it was in the beginning and this is awfully discouraging and frustrating. The scope of your project has suddenly tripled and your todo list is a never-ending tally of bug fixes and re-factors and speed optimizations that need to be addressed for any chances of your game seeming like it’s something worth playing.

Early demo failures and monotonous repetition

If you’ve made it far enough to put together early demos and alpha access then pat yourself on the back — most people will never make it this far and you’ve just become a member of an elite club that deserves a badge of honor. The only problem is your demo gets horrible reviews, you realize your controls are too hard to use and this puts you into a crazy monotonous cycle of playing a particular part of your game over and over again as you attempt to fine tune it and make it more playable and more fun.

Never good enough

Unfortunately the truth is that your game will never be good enough. Someone will always find something to complain about even if you see some great feedback and helpful critiques that, if implemented, could really take your game to the next level and set you apart from your competition. Your controls will never be 100% perfect, your menu system may be too hard to read or too complex to navigate and you’ll never quash all the bugs that have been reported partly because you can’t re-create them all because your game is being run and tested under hundreds of different environments and hardware and operating systems that you didn’t have access to (and probably never will) as you were developing. If you’ve made it here this might just be the time for you to throw in the towel and say goodbye to all the blood, sweat and tears you succumbed to in order to make it this far.

Overcoming It All

If this has discouraged you against making your own game — good. Making a game isn’t easy and it’s not something for everyone so don’t waste your time early on if you’re not prepared to go through everything I’ve already mentioned and be able to walk away without anything to show for it. However that doesn’t mean you shouldn’t make a game or that it’s impossible to do it either. Where there is a will there’s a way and let me show you how.

  • Map out your game design, features, characters and how the game works. Now create lots of small, easy tasks you can accomplish in order to see your core game mechanics to completion enough that you could play a simple version of your game without any extra bells and whistles. Set yourself up to do as little as you have to but as much as you need to in order to get a completed version of your game.
  • If you lack the skill to do something you have two options. The first is that you resign yourself to taking the time to learn this new skill and the next is that you can outsource the skill to someone who’s already achieved it. You don’t have to be an expert programmer to make a game, just an adequate one. If you’re going to invest time into learning a new skill don’t dwell on it for too long, learn enough that you feel confident you can accomplish the task at hand and then move on. Investing too much time in learning a skill will start you down a path that walks further and further away from working on your game.
  • Sit down and map out all of the expenses you foresee as being necessary to complete your game. Now triple it. If you can’t afford to spend this amount of money into your game then you need to go back to your concept and re-work it until you get a budget that you can work with. If you’re really determined you can look for some outside investors but don’t count on this — ever. Most investors want to see a fully working demo before they’ll even consider opening their pocketbooks and investors will demand more than 50% of whatever profits you make from your game when it’s done.
  • Your time is precious when you have so little of it to devote to your game. Start by mapping out a timeline of your game features/assets and how long you think it will take you to accomplish them. Now double that. Now compare that to how much free time you really have to devote to your game. Will this game take you more than a year to complete? Do you have the dedication to spend more than a year working on a single project? If the answer is no then you need to go back to the drawing board until you’ve come up with a reasonable timeline that you can work with. Keep your game as small as you possibly can by focusing on the core mechanics and leaving out any fluff that you could add at a later date. Now stick to your timeline. If you budget 2 weeks to work on a character and by the end of the second week the character isn’t done don’t dwell on it — either move on to the next item in your list. Don’t adjust your timeline and don’t spend more time that you budgeted on this part of it. Sure, your ultimate goal is to have a working character with great animation but if you can’t ever get a game working with a broken character then who cares if your character’s animation is jerky or unrealistic? Think about the big picture because you can always circle back later.
  • Invest in a good debugger and testing tools. Do whatever you can to automate this process as much as possible because it will give you more time to work on trivial issues when you can quickly address and fix the larger ones. If you run into a bug that makes your game do something funky but it doesn’t prevent the gameplay from continuing table it and work on something else. Try not to get caught up in the more minute issues and focus more on the big picture. You can always circle back and fix bugs later but if you spend all your time bug quashing you’ll end up with a pretty interface or character or scene that doesn’t let interact and play with it. Pick a version of a framework and stick with it, don’t upgrade it unless you absolutely have to. The more you upgrade and update to the latest and greatest the more issues you’ll run into and the more refactoring and scope creep you’ll run into. It’s okay to build a game that isn’t using the latest and greatest version of your frameworks or 3rd party integrations. This will also give you a chance to work with and around the quirks in the version of the framework/software you chose to use instead of having to re-work around these every time you upgrade and re-factor.
  • Get the core mechanics working version of your game finished as early as possible no matter what it looks like or how bad it is. A crappy, ugly, glitching yet working version of your game is better than a pretty, perfectionist, bug free version of your game that isn’t at all playable. Don’t wait until the last minute or the week before it opens to get feedback on what you’re doing. Feedback is a great way to find issues you hadn’t considered and it will give you an idea of what other people think about your game. After all, no one wants to play a game they don’t think is fun. Don’t ignore constructive criticism even if it’s not what you want to hear. That doesn’t mean you have to change or add anything anyone has ever asked you for — it means that you need to take those things into consideration going forward. See past the reviews that focus on your aesthetics — at least initially — because you can always change and fix those later, core mechanics and gameplay are much harder to tackle once you’ve invested lots of time and energy into them.
  • Your game will NEVER be perfect. You will always be tweaking, adding, adjusting and fine tuning it. Instead of wasting your time doing this early on and ending up with something that isn’t a viable product devote that time to your game after you have something you can put out there. Don’t be a perfectionist, no matter how many bugs you quash and features you add or tweak there will always be another bug or problem coming down the pipeline. Try to prioritize the most important ones and tackle those first. Ultimately you want to get something up and working no matter how good or bad it is and then build upon it from there. Rome wasn’t built in a day so don’t expect your game to be. Get a working version up first and foremost and then add on to it and enhance it over time, your customer base won’t hate you for that, rather the opposite — they’ll appreciate your continued efforts to improve upon what you’ve done so far.

MySQL Tutorial: Archiving and Loading Archived Table Data

Leave a comment Standard

Let’s say you have a really large table and you want to archive the data to a new table so that your main table is smaller again. This is useful with things like chat logs or game logs which grow large really quickly but you don’t want to lose the data or you want to keep a history of it. Making an archive table from the main table allows you to truncate the main table for faster queries.

Create the Archive Table

If you want to save the contents of the table into another archive table you’ll need to create a copy of the original table with all the same indexes and schema:

CREATE TABLE your_new_archive_table LIKE the_table_you_want_to_archive;

Dump the Data into the Archive Table

Now you have an archive table that matches your original table let’s dump the data into it:

INSERT your_new_archive_table * FROM the_table_you_want_to_archive;

Dump the Data into a SQL file

If you prefer to save your data to a file on the server rather than in another table you can archive it this way instead. Make sure your file has saved and has data in it before you truncate your original table.

SELECT * FROM the_table_you_want_to_archive INTO OUTFILE '/save_path/your_new_archive_table .sql';

Test the Archive Table

Make sure your table has data in it by looking at your new archive table:

SELECT * FROM your_new_archive_table LIMIT 100;

Test the Archive File

Go to the command line and check to make sure you file was created and has data in it by typing the following:

cat /save_path/your_new_archive_table.sql

Empty the Original Table

Make sure your archive table or archive file has data in it before you empty your original table.

TRUNCATE TABLE the_table_you_want_to_archive;

Load an Archive Table Back Into the Original Table

If you decide you want to load your archived data back into the original table you can do the following.

INSERT the_table_you_want_to_archive * FROM your_new_archive_table;

Load an Archive File Back Into the Original Table

Once you have an archive file you can load it back into your database by doing the following:

LOAD DATA INFILE '/save_path/your_new_archive_table.sql' INTO TABLE the_table_you_want_to_archive;

PHP Tutorial: Run Multiple Tic-Tac-Toe Game Instances (no database required)

Leave a comment Standard
Multi Instance Tic Tac Toe

Someone asked me about this in a comment recently so this post is specifically for you but I’m sure there are other people who will benefit from it as well. If you haven’t read the tic-tac-toe game tutorial yet then you’ll need to start there. This tutorial assumes you’ve already completed that and now you want to run two or more tic-tac-toe boards on the page simultaneously.

Or if you want to skip this tutorial you can
download the source code or try the working example

Concepts

The neat thing about classes is that you can use them to create multiple instances with varying states and data even though they all have the same methods and properties. Think about a monster RPG game. Each monster has a different name and breed and picture and strength — but they all have those things in common even though the values are different. Our tic tac toe class works the same way, we can create multiple instances of the game and they’ll each have different states — whose turn it is, which places on the board are filled — but they’ll all work the same way. In order to run multiple instances of our tic tac toe games we’re going to have to update our games so they can be uniquely identified by an instance number. The reason for this is so that when you play the game on instance 1 we know you want to update the state of instance 1 when you submit the form. If we didn’t give each game it’s own instance identifier then every time you made a move on one board it would reflect that move on all instances of the board at the same time.

Creating The Instance Form

Let’s change our index file so that we’re allowing the user to choose how many instances of the game they want to play. We start by removing where we created a new game from the top of the file. Since we want multiple instances we need to create the new game for every instance we have and since we don’t know how many instances we have at this point it needs to move down in our code base. Now once the user has selected how many instances of the game they want to play we need to dynamically generate that many. Using a for loop we loop through the number of instances they selected and create a game for each of those instances in our new $_SESSION[‘game’] array. Before this was only a single game, making it an array means we now have multiple games in our game session variable. Finally we create a new game instance and tell it to start playing. This is what our new index file looks like.

<?php
/***
* File: index.php
* Author: design1online.com, LLC
* Created: 4.6.2015
* License: Public GNU
* Description: PHP/MySQL Version of 2 Player Tic Tac Toe
* that allows playing multiple instances of the game at the same time
***/
require_once('oop/class.game.php');
require_once('oop/class.tictactoe.php');

//this will store their information as they refresh the page
session_start();

define('MAX_INSTANCES', 5); //the maximum number of games they can play at the same time

//trying to set number of instances to play
if (isset($_POST['instances'])) {
 if (is_numeric($_POST['instances']) && $_POST['instances'] > 0) {
 $_SESSION['instances'] = $_POST['instances'];
 }
}

?>
<html>
 <head>
 <title>Tic Tac Toe - Multiple Instances</title>
 <link rel="stylesheet" type="text/css" href="inc/style.css" />
 </head>
 <body>
 <div id="content">
 <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
 <h2>Let's Play Tic Tac Toe!</h2>
 <?php
 //we need to know how many instances to create
 if (!isset($_SESSION['instances'])) {
 ?>
 <p>How many games would you like to instantiate?</p>
 <select name="instances">
 <?php
 for ($i = 1; $i <= MAX_INSTANCES; $i++) {
 echo "<option value=\"$i\">$i</option>";
 }
 ?>
 </select>
 <input type="submit" name="submit" value="Let Me Play!" />
 <?php
 } else {
 echo "<table width=\"100%\">
 <tr>";
 
 for ($i = 1; $i <= $_SESSION['instances']; $i++) {
 
 //if they haven't started a game yet let's load one
 if (!isset($_SESSION['game'][$i]['tictactoe'])) {
 $_SESSION['game'][$i]['tictactoe'] = new tictactoe($i);
 }
 
 echo "<td>";
 
 //play the game passing it the game data for that instance
 $_SESSION['game'][$i]['tictactoe']->playGame($_POST);
 
 echo "</td>";
 }
 
 echo "</tr>
 </table>";
 }
 ?>
 </form>
 </div>
 </body>
</html>

Adding Instances To The Class

The first thing we need to do is add an instance identifier to our tictactoe class. Since we need to know which game the player is trying to play adding a $this->instance value to our class will let us keep track of which game is which. Once that’s done we update our checks for $_POST data to make sure we’re using the correct data for the correct instance. Voila! Our games now only update when they see $_POST data that pertains to them. Our new tictactoe class file looks like this:

<?php
/***
* File: oop/class.tictactoe.php
* Author: design1online.com, LLC
* Created: 1.31.2012
* License: Public GNU
* Description: tic tac toe game
***/

class tictactoe extends game
{
 var $instance = 0; //the instance of this game
 var $player = "X"; //whose turn is
 var $board = array(); //the tic tac toe board
 var $totalMoves = 0; //how many moves have been made so far 

 /**
 * Purpose: default constructor
 * Preconditions: none
 * Postconditions: parent object started
 **/
 function tictactoe($instance)
 {
 /**
 * instantiate the parent game class so this class
 * inherits all of the game class's attributes 
 * and methods
 **/
 $this->instance = $instance;
 game::start();
 
 $this->newBoard();
 }
 
 /**
 * Purpose: start a new tic tac toe game
 * Preconditions: none
 * Postconditions: game is ready to be displayed
 **/
 function newGame()
 {
 //setup the game
 $this->start();
 
 //reset the player
 $this->player = "X";
 $this->totalMoves = 0;
 
 //reset the board
 $this->newBoard();
 }
 
 function newBoard() {
 
 //clear out the board
 $this->board = array();
 
 //create the board
 for ($x = 0; $x <= 2; $x++)
 {
 for ($y = 0; $y <= 2; $y++)
 {
 $this->board[$x][$y] = null;
 }
 }
 }
 
 /**
 * Purpose: run the game until it's tied or someone has won
 * Preconditions: all $_POST content for this game
 * Postconditions: game is in play
 **/
 function playGame($gamedata)
 {
 if (!$this->isOver() && isset($gamedata[$this->instance . 'move'])) {
 $this->move($gamedata);
 }
 
 //player pressed the button to start a new game
 if (isset($gamedata[$this->instance . 'newgame'])) {
 $this->newGame();
 }
 
 //display the game
 $this->displayGame();
 }
 
 /**
 * Purpose: display the game interface
 * Preconditions: none
 * Postconditions: start a game or keep playing the current game
 **/
 function displayGame()
 {
 
 //while the game isn't over
 if (!$this->isOver())
 {
 echo "<div id=\"board\">";
 
 for ($x = 0; $x < 3; $x++)
 {
 for ($y = 0; $y < 3; $y++)
 {
 echo "<div class=\"board_cell\">";
 
 //check to see if that position is already filled
 if ($this->board[$x][$y])
 echo "<img src=\"images/{$this->board[$x][$y]}.jpg\" alt=\"{$this->board[$x][$y]}\" title=\"{$this->board[$x][$y]}\" />";
 else
 {
 //let them choose to put an x or o there
 echo "<select name=\"{$this->instance}_{$x}_{$y}\">
 <option value=\"\"></option>
 <option value=\"{$this->player}\">{$this->player}</option>
 </select>";
 }
 
 echo "</div>";
 }
 
 echo "<div class=\"break\"></div>";
 }
 
 echo "
 <p align=\"center\">
 <input type=\"submit\" name=\"{$this->instance}move\" value=\"Take Turn\" /><br/>
 <b>It's player {$this->player}'s turn.</b></p>
 </div>";
 }
 else
 {
 
 //someone won the game or there was a tie
 if ($this->isOver() != "Tie")
 echo successMsg("Congratulations player " . $this->isOver() . ", you've won the game!");
 else if ($this->isOver() == "Tie")
 echo errorMsg("Whoops! Looks like you've had a tie game. Want to try again?");
 
 echo "<p align=\"center\"><input type=\"submit\" name=\"{$this->instance}newgame\" value=\"New Game\" /></p>";
 }
 }
 
 /**
 * Purpose: trying to place an X or O on the board
 * Preconditions: the position they want to make their move
 * Postconditions: the game data is updated
 **/
 function move($gamedata)
 { 

 if ($this->isOver())
 return;

 //remove duplicate entries on the board 
 $gamedata = array_unique($gamedata);
 
 foreach ($gamedata as $key => $value)
 {
 if ($value == $this->player)
 { 
 //update the board in that position with the player's X or O 
 $coords = explode("_", $key);
 
 //make sure we use the data from the right instance
 if ($coords[0] == $this->instance) {
 $this->board[$coords[1]][$coords[2]] = $this->player;

 //change the turn to the next player
 if ($this->player == "X")
 $this->player = "O";
 else
 $this->player = "X";
 
 $this->totalMoves++;
 }
 }
 }
 
 if ($this->isOver())
 return;
 }
 
 /**
 * Purpose: check for a winner
 * Preconditions: none
 * Postconditions: return the winner if found
 **/
 function isOver()
 {
 //top row
 if ($this->board[0][0] && $this->board[0][0] == $this->board[0][1] && $this->board[0][1] == $this->board[0][2])
 return $this->board[0][0];
 
 //middle row
 if ($this->board[1][0] && $this->board[1][0] == $this->board[1][1] && $this->board[1][1] == $this->board[1][2])
 return $this->board[1][0];
 
 //bottom row
 if ($this->board[2][0] && $this->board[2][0] == $this->board[2][1] && $this->board[2][1] == $this->board[2][2])
 return $this->board[2][0];
 
 //first column
 if ($this->board[0][0] && $this->board[0][0] == $this->board[1][0] && $this->board[1][0] == $this->board[2][0])
 return $this->board[0][0];
 
 //second column
 if ($this->board[0][1] && $this->board[0][1] == $this->board[1][1] && $this->board[1][1] == $this->board[2][1])
 return $this->board[0][1];
 
 //third column
 if ($this->board[0][2] && $this->board[0][2] == $this->board[1][2] && $this->board[1][2] == $this->board[2][2])
 return $this->board[0][2];
 
 //diagonal 1
 if ($this->board[0][0] && $this->board[0][0] == $this->board[1][1] && $this->board[1][1] == $this->board[2][2])
 return $this->board[0][0];
 
 //diagonal 2
 if ($this->board[0][2] && $this->board[0][2] == $this->board[1][1] && $this->board[1][1] == $this->board[2][0])
 return $this->board[0][2];
 
 if ($this->totalMoves >= 9)
 return "Tie";
 }
}

Conclusion

Try the working example! In this tutorial we talked about instances and how you can use a class to dynamically create multiple instances each of which keep track of their own state and values. If you’ve been following my game tutorials then I hope you’re starting to see how powerful classes are and how iterative improvements can be used to enhance your gameplay, functionality and user experience.

HTML5 Tutorial: Simple Music Player

Leave a comment Standard
HTML5 Music Player

So this is a pretty simple example but I was playing around with flash for my chat room and this was byproduct of that experimentation. It’s funny how even when I’m trying to learn something new I do my best to make it useful for other situations which is a good habit to get into if you’re not doing it already.

Try out the working demo or download the code

Caveats

This will only work on a browser that is HTML5 compliant and has support for audio. That means older browsers and most versions of Internet Explorer are not supported. Firefox, Chrome and Opera work as well as the newest versions of Internet Explorer.

The Audio Tag

If you’re familiar with HTML then most of the index file below will look pretty familiar. The thing you really have to pay attention to is the new <audio> tag. It looks like this:

<audio id="rock" src="http://whiteoakstables.net/chat/audio/rock.wav" preload="auto"></audio>

You may notice that it looks a whole lot like a hyperlink with the src that defines the location of the file. Preload is an optional attribute, it tells your browser to start downloading the file as soon as the DOM, or page elements, have finished loading. In addition to setting preload to true I’ve added an ID attribute so I can reference this particular song in my music player.

The Index File

<!DOCTYPE html>
<html>
 <head>
 <script data-require="jquery@*" data-semver="2.1.3" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
 <link data-require="bootstrap-glyphicons@*" data-semver="3.2.1" rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/img/glyphicons-halflings.png" />
 <link data-require="bootstrap@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
 <script data-require="bootstrap@*" data-semver="3.3.1" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
 <link rel="stylesheet" href="style.css" />
 <script src="script.js"></script>
 </head>
 <body>
 <h1 class="text-center">Bootstrap HTML5 Music Player</h1>
 <audio id="rock" src="http://whiteoakstables.net/chat/audio/rock.wav" preload="auto"></audio>
 <audio id="blues" src="http://whiteoakstables.net/chat/audio/blues.wav" preload="auto"></audio>
 <audio id="electronica" src="http://whiteoakstables.net/chat/audio/electronica.wav" preload="auto"></audio>
 <audio id="classical" src="http://whiteoakstables.net/chat/audio/classical.wav" preload="auto"></audio>
 <audio id="latin" src="http://whiteoakstables.net/chat/audio/latin.wav" preload="auto"></audio>
 <audio id="indie" src="http://whiteoakstables.net/chat/audio/indie.wav" preload="auto"></audio>
 <div class="audiocontroller">
 <i class="audio-logo glyphicon glyphicon-headphones"></i>
 <i class="dynamiclink glyphicon glyphicon-play" id="play"></i></a>
 <i class="dynamiclink glyphicon glyphicon-pause" id="pause"></i>
 <select id="currentTrack">
 <option value="rock">Rock</option>
 <option value="blues">Blues</option>
 <option value="electronica">Electronica</option>
 <option value="classical">Classical</option>
 <option value="latin">Latin</option>
 <option value="indie">Indie</option>
 </select>
 <i class="dynamiclink glyphicon glyphicon-stop" id="stop"></i>
 </div>
 <p class="text-center">
 <a id="author" href="http://design1online.com" target="_blank">by Design1online.com, LLC</a>
 </p>
 </body>
</html>

The Javascript File

//Simple HTML5 Music Player by design1online.com, LLC

var currentTrack = null;
var paused = false;

$(document).ready(function() {
 currentTrack = $('#currentTrack').val();
 
 $("#play").click(function() { play(); });
 $("#stop").click(function() { stop(); });
 $("#pause").click(function() { pause(); });
});

function play() {

 //set the track back to the beginning
 if (!paused) {
 stop();
 currentTrack = $('#currentTrack').val();
 
 //make sure track starts from the begining each time
 document.getElementById(currentTrack).load();
 }

 //play the track
 document.getElementById(currentTrack).play();
}
 
//stop playing the current track
function stop() {
 if (currentTrack) {
 document.getElementById(currentTrack).pause();
 paused = false;
 }
}

//stop the track but don't go back to the beginning
function pause() {
 paused = true;
 document.getElementById(currentTrack).pause();
}

How It All Works

So now let’s talk about the javascript file. At first glance it looks relatively simple because it is! When you want to select a track you simply ask for it using getElementById and then you tell it to play or to pause. One thing that is sadly lacking is a stop() functionality. With html5 you can only pause an audio file — which does stop the playback but it also keeps the audio file at the same position as when you called pause on it. This means that if you wanted to play the audio file from the beginning again and you just called play() it would continue playing from where it left off. That’s where the load() function comes into play — this will tell the audio track to start loading if it wasn’t set to preload and it will reset the track back to the beginning.

The only other thing to mention is the currentTrack variable. I use this to keep track of which of the songs is currently selected and the user wasn’t to listen to.