Blog

PHP/Laravel: Input::all() and Input::file(‘files’) coming back as empty arrays when uploading large files (videos/images)

Are you trying to implement an image or video uploader in your PHP project, specifically a Laravel 4+ project, and you find that the upload HTTP POST is indeed hitting your controller method but Input::all(), Input::file(‘files’), and $_FILES are all empty arrays? Well there is a really good chance its not your front-end nor your back-end code that is the problem, its most likely its PHP playing a cruel trick on you. According to the PHP documentation, if the php.ini default settings are in play, PHP is restricting file uploads that are bigger than the default size of 8 megabytes.

Yes that is correct, in today’s modern world of web development and today’s internet of media, the makers of PHP have decided that file uploads should still be restricted to a file size more appropriate for the late 1990’s. But on top of that, instead of providing a warning message in the HTTP Request object that the limit is being exceeded, PHP just simply removes the request objects all together and pretends nothing was submitted with the request at all, leaving the developer in a complete state of profound confusion.

That being said, go change your defaults (CentOS specific):

nano /etc/php.ini

Search for each of these default keys and set the values you feel best fit your needs:

memory_limit = 4000M
upload_max_filesize = 1000M
post_max_size = 1500M

Restart the Apache service:

service httpd restart

Building JWPlayer v6.12 from Source (for the rest of us)

Building JWPlayer v6.12 from Source with an Embedded RTMPE Secret Key for use with Protected Wowza Server (for the rest of us)

Last Updated: 04/29/2015

Used to rebuild the current version of the player with an embedded secret code for use with the Wowza RTMPE stream security protocol. Must be built on a machine that can run old 32-bit versions of Java specifically the 1.5 JDK (this rules out OS X after Mavericks as Apple does not support it).

Build Machine Setup

Requirements

  • 32-bit Windows XP/7/8.1
  • 32-bit Java 1.5
  • Ant 1.7.0
  • Adobe Flex SDK 4.5.1

Installing Java 1.5

URL: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase5-419410.html

  1. Set the JAVA_HOME environment variable to the installation location of Java JDK root folder (usually C:\Program Files\Java\jdk1.5.0_22)
  2. Add the bin directory of the Java JDK to your system’s PATH environment variable by referencing the JAVA_HOME environment variable, this makes it so there is only one place that the Java JDK path needs to updated (%JAVA_HOME%\bin)
  3. Close all Command Prompt windows if any are open as they will not have the changes to the path you made until reopened
  4. Verify the system is now using Java 1.5 by opening a clean Command Prompt and executing the command java -version

Installing Apache Ant 1.7.0 (open build platform used in the Java world)

URL: http://archive.apache.org/dist/ant/binaries/

  1. Download the binary zip and extract it
  2. Copy the extracted folder to the C drive (C:\apache-ant-1.7.0)
  3. Add the Ant bin folder to the Windows PATH environment variable (C:\apache-ant-1.7.0\bin)
  4. Close all Command Prompt windows if any are open as they will not have the changes to the path you made until reopened
  5. Verify the system is now using Ant 1.7 by opening a clean Command Prompt and executing the command:

ant -version

Installing Flex SDK 4.5.1

URL: http://sourceforge.net/adobe/flexsdk/wiki/Download%20Flex%204.5/

  1. Create a new folder in the C drive called JWPlayer (C:\JWPlayer)
  2. Download the SDK zip archive and extract the contents to the JWPlayer folder (C:\JWPlayer\flex_sdk_4.5.1.21328A)

Installing the JWPlayer Source

URL: https://github.com/jwplayer/jwplayer/tree/release

  1. Download the 6.12 release of the JWPlayer source code (at this time it is the current release and is therefore in the release branch on GitHub, this will change as new releases come out)
  2. Extract the archive to the JWPlayer folder you created early (C:\JWPlayer\jwplayer-release-6.12)

Building the Player from Source

Update Build Properties

  1. Open the build.properties file located in the JWPlayer source folder you just extracted (C:\JWPlayer\jwplayer-release-6.12\build\build.properties)
  2. On line 11 change the ‘flexsdk’ key with the location of the Flex SDK, you must use Unix style file path (flexsdk = C:/JWPlayer/flex_sdk_4.5.1.21328A)
  3. On line 16 change the ‘execextension’ key with a ‘.exe’ as we are using Windows to build (execextension = .exe)
  4. Save and close the file

Update Player Version

  1. Open the PlayerVersion.as file (C:\JWPlayer\jwplayer-release-6.12\src\flash\com\longtailvideo\jwplayer\player\PlayerVersion.as)
  2. On line 5 change the value “JWPLAYER::version” to “6.12.0”

Adding the Secret Key

  1. Open the RTMPMediaProvider.as file (C:\JWPlayer\jwplayer-release-6.12\src\flash\com\longtailvideo\jwplayer\media\RTMPMediaProvider.as)
  2. On line 491 change var hash:String = TEA.decrypt(evt.info.secureToken, getConfigProperty(‘securetoken’)); to var hash:String = TEA.decrypt(evt.info.secureToken, “VALUE_OF_NEW_SECRET_KEY_GOES_HERE”);

Building

  1. Open a Command Prompt at the root of the JWPlayer’s source folder (C:\JWPlayer\jwplayer-release-6.12)
  2. Execute the command

ant -buildfile build\build.xml

Troubleshooting

So many different things can go wrong, way too many to list in this document, Google is a great resource 😉

Release Binaries

New player should be located in bin-release if the build was successful
Assets Created jwplayer.js, jwplayer.html5.js, jwplayer.flash.swf

Notes:

Adding a JAVA_HOME environment variable to your system and adding Java to your PATH by referencing JAVA_HOME, instructions can be found here https://kaanmutlu.wordpress.com/2013/04/26/setting-the-java_home-in-windows-7-64-bit/

2.23 – Apps must follow the iOS Data Storage Guidelines or they will be rejected [FIXED]

If you have run into an iOS application rejection based on the 2.23 iOS guideline regarding an application exceeding fair use of the iCloud backup storage then you will need to make sure all files your application downloads or creates, that are not user specific and that do not need to be backed up, are removed from the iCloud backup set for the application. This can be done by applying the NSURLIsExcludedFromBackupKey key to all of those files using the following method.

You can add this method to your AppDelegate or some other singleton within your application and have access to it from anywhere within your project using the following code:

// Make sure file is removed from the iCloud image backup system
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate addSkipBackupAttributeToItemAtURL:imagePath];

// Removes all application assets that are not user created from the iCloud backup system
// by adding the NSURLIsExcludedFromBackupKey to every file that is downloaded and stored
// in the application's document directory
-(BOOL)addSkipBackupAttributeToItemAtURL:(NSString *)fileString {
    
    // Convert string path to NSURL
    NSURL * fileURL = [NSURL fileURLWithPath:fileString];
    
    // Make sure file has already been created before applying key
    if (![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) {
        NSLog(@"File Missing: %@",[fileURL path]);
        return NO;
    }
    
    // Obtain iOS version for proper key application
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    
    // 5.0.1 requires <sys/xattr.h>
    if ([currSysVer isEqualToString:@"5.0.1"]) {
        const char* filePath = [[fileURL path] fileSystemRepresentation];
        const char* attrName = "com.apple.MobileBackup";
        u_int8_t attrValue = 1;
        int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
        NSLog(@"Excluded '%@' from backup",fileURL);
        return result == 0;
    }
    // Above 5.0.1 use NSURLIsExcludedFromBackupKey key
    else if (&NSURLIsExcludedFromBackupKey) {
        NSError *error = nil;
        BOOL result = [fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
        if (result == NO) {
            NSLog(@"File '%@' could not be excluded from iCloud backup set. Error: %@",fileURL, error);
            return NO;
        }
        else {
            NSLog(@"File '%@' has been removed from iCloud backup set.",fileURL);
            return YES;
        }
    } else {
        // iOS version is below 5.0, no need to do anything
        return YES;
    }
}

MySQL: Grant Root Access from Any IP

Warning: Not a good idea on a production database. I use this only for local dev environments when I have virtual machines running via a bridged connection and DNS changes often.

Log into MySQL on the server machine via the command line
mysql -u root -p

Using the MySQL wildcard ‘%’ in place of an IP
GRANT ALL ON *.* to root@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;

JavaScript: Unobtrusive

It all comes down to separation of concerns. When programming, separation of concerns deals with creating clear and concise boundaries between application components that have different responsibilities but work together to carry out a common overarching goal. So it is with the development of web user interfaces using HTML5, CSS3, and JavaScript. Each of these technologies work together to create interactive and beautiful user interfaces within the browser, but they each have very specific jobs that make these interfaces possible.

HTML: structures content in a very semantic (meaningful) and ordered way.

CSS: beautifies HTML by adding visual enhancements such as color, gradients, borders, padding, margin, fonts, animations, and  positioning.

JavaScript: adds behavior to HTML, allowing HTML to respond to DOM events as users interact with the web page within the browser.

Together these three technologies create a very powerful tool set for the modern web developer and web user interface designer. The difficult part for most web developers is not allowing the three, very closely related technologies, to bleed across their boundaries into each other creating tightly coupled code. This tightly coupled code is usually a result of CSS and JavaScript being placed directly in the HTML.

Unobtrusive method to the rescue. Merriam-Webster defines the word unobtrusive as not attracting attention in a way that bothers or annoys. Well, mashed together HTML, CSS, and JavaScript is bothersome and extremely annoying, especially when it comes to maintainability and defect repair. For this reason developers have begun to make sure their web user interfaces are completely separated. This is accomplished by following a few specific rules:

HTML

  1. keeping HTML markup in separate files

CSS

  1. keeping CSS markup in separate files
  2. referencing those files in the ‘head’ element of the HTML files
  3. never use ‘style’ elements in HTML
  4. never use ‘style’ attributes on HTML elements

JavaScript

  1. keeping JavaScript markup in separate files
  2. referencing those files in the ‘head’ element or at the bottom of the ‘body’ element of the HTML files
  3. never use ‘script’ elements to hold JavaScript code in HTML
  4. only use ‘script’ elements to references a JavaScript file
  5. never use HTML element attributes that bind to DOM events such as ‘onclick’ or ‘onmouseenter’

Unobtrusive JS Example:

<!--DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>JavaScript Event Binding</title>
    <script src="jsEventBinding.js"></script>
</head>
<body>
    <div id="click-me">Click Me</div>
</body>
</html>
/**
 * Created by Tim on 9/9/14.
 */

'use strict';

var elem = document.getElementById('click-me'); // a DOM element
elem.onclick = function () {
    // Do something nifty here
};

JavaScript: The Event Loop

JavaScript is event based, meaning everything that happens within a browser window/tab is the result of an event occurring and code responding to that event. There are hundreds of potential events that may need to be responded to throughout the life-cycle of an HTML page.

An important concept to understand, when it comes to JavaScript and the browser, is the event loop, the primary driver of this event based system. The event loop is controlled and managed by the browser which keeps the loop running and dispatches all events as they occur. Due to this, developers are free to focus 100% of their energy on identifying the events they are interested in and writing logic to respond accordingly to those events. This code that is invoked in response to an event is called an ‘event handler’ or ‘listener’.

One of the most complex parts of JavaScript programming is the fact that events are fired unpredictably and in an unpredictable order. This means JS code has to be written in an asynchronous manner with each listener having the ability to be executed independently of all others.

Unlike a lot of other languages out there, the JavaScript event loop is ‘non-blocking’ meaning that JavaScript does not allow the event loop to be monopolized by any single function. This includes I/O (input/output) events, instead of waiting for a file read to complete or a database call to return before moving on, JavaScript requires a listener to be provided and assigns that listener to the I/O return event and it moves on. Ultimately what this does is keep the browser window responsive and usable while long running tasks are taken care of asynchronously. This is a huge advantage being that the browser window is the user interface, which should remain responsive at all times.

Reference: Mozilla Developer Event Loop

To get an idea, here are just some of the most common events that front-end developers deal with on a daily basis, of course there are many more that are just as important as these:

Window Events

  • onload: fires after the page finished loading
  • onerror: fires when an error occurs
  • onresize: fires when the browser window is resized
  • onunload: fires when the page is unloaded or browser window closes

Keyboard Events

  • onkeydown: fires when the user presses a key down and holds it down
  • onkeypress: fires when the user presses a key down and then releases it
  • onkeyup: fires when the user releases the key

Mouse Events

  • onclick: fires when the user clicks on an HTML element
  • ondblclick: fires when the user double clicks on an HTML element
  • ondrag: fires when the user drags an HTML element
  • onmouseover: fires when a user hovers the mouse cursor over an HTML element
  • onmousemove: fires when a user moves the mouse cursor over an HTML element

Reference: Mozilla Developer Web Events