OCI_COMMIT_ON_SUCCESS

I received the following error in my CodeIgniter web application today:

Notice: Use of undefined constant OCI_COMMIT_ON_SUCCESS – assumed ‘OCI_COMMIT_ON_SUCCESS’ in …

today. It turns out that, in MEPIS at least, you need the packages bc, libaio, even if you’ve compiled support for oci8. I re-added the packages, restarted Apache and it worked, once again.

Advertisements

Back to CI

Yes, as above.

I’ve taken on a new position at a new company, and my lead developer has decided that we go with CodeIgniter, so I will switch back to this.

Wish me luck!

CodeIgniter: Controller::view() results in a "404 not found" error in PHP v4.4.2

If you have a controller “Blah” and a method “view”, accessing it via the browser like:

http://path/to/ci/index.php/blah/view

results in a “404 not found” error if your PHP installation is PHP v4.4.2. Not verified for any other 4.x versions.

The same code works in PHP 5.2.0-8+etch5, so I believe it is a bug, possibly in system/codeigniter/Base4.php.

I tried to support a bug report, but I need to be registered first, but the registration form for the forums is broken. So here is my bug report.

CodeIgniter: jQuery $.ajax goodness

I’ve been using the jQuery JavaScript library for sometime now. It actually makes writing client-side programming fun, wow! The AJAX functionality is a joy to use; you can submit requests as POST instead of GET since the former is not available in the CodeIgniter PHP framework.

Say you have a controller user.php and a view user_add.php. Now you want to submit an AJAX request to the server to check if the (presumably unique) username field is available for use.


$(document).ready(function() { // user_add.php
	$('#username').blur(function() {
		$.ajax({
			url: 'username_callback/' + $(this).val(),
			type: 'post',
			success: function(result) {
				$('#username_check').attr('innerHTML', result);
			}
		});
	});
});

// html: user_add.php


So we’ve added an anonymous function to the username element. When it loses focus, we’ll submit a POST request to your your user controller, username_callback method. On success, we’ll replace the content (innerHTML) of the span username_check with the value returned by the PHP function.

I’m using the site_url() helper function to get my CI installation URL. NOTE: You’ll need to include this in the user.php constructor or in the autoloader.

// php: user.php

class User extends Controller
{
	function User()
	{
		parent::Controller();
		$this->load->helper('url');
	}

	function username_callback()
	{
		$s = trim(strip_tags($_POST['username'])); // clean

		if ($s == 'admin') { // error
			print 'The username 'admin' is reserved.'
		}
	}
}

username_check() will check if the POST-ed parameter is ‘admin’, and complain if so. So there you have it. That wasn’t too difficult, wasn’t it?

P.S. I would have loved to post up a working example but WP won’t accept .zip files.

Codeigniter: Strange Image_lib error resolved

I was writing a CodeIgniter-based app which accepts an image (gif|jpg|png) from the browser and resizes it using calls to Image_lib.php library. Everything was going well on my development machine, even for large (1600×1200 pixels) JPEGs.

Then I got a call informing me that if you uploaded images greater than a certain width/height — size constraint was already in place — the script would fail. A blank page was returned.

I was puzzled since I distinctly remembered that we had taken in larger images before without any issues. I thought it might be the Upload.php library, but then no, the file was being uploaded successfully.

It took some determination to produce the stack trace:

blah::_resize('blah.jpg'); // in blah.php controller
Image_lib::resize(); // ... now in Image_lib.php library
Image_lib::image_process_gd('resize');
Image_lib::image_create_gd('blah.jpg', 2); // some file, jpg image type
imagecreatefromjpeg(); // called by image_create_gd(): dies at this point

At this point I was sorely wishing that PHP had a better way of setting breakpoints than just using print_r and die. Best is to have a “Watched Expressions” feature so we can really figure out at which point did the script (abnormally) terminate.

Scroll down a little for the answer — my ex-colleague who is an experienced programmer gave me the answer, in like 3 minutes.

.
.
.
.
.
.
.
.
.
.

The problem was with the php.ini setting memory_limit. It was set to 8M on the staging server, whereas it was 16MB on my development machine. Restarting Apache with the value set to 16MB solved the problem! Gah!

Accessing an alternate database from a CodeIgniter hook

I was writing a url-based access control hook for this CI web app recently, and I was scratching my head how to access a database from the hook.

The standard $this->load->database() call doesn’t work because we are not within a controller, and then I stumbled upon the get_instance() method:

$CI =& get_instance();
$CI->load->database();
$query = $CI->db->get("groups");

Now I began my development on the frontend to setup the permissions itself, so I had always thought that the 2nd statement was working well.

When I began applying the hook to the actual app, I found that $ci->db actually referred to the default database that is specified in system/application/config/database.php even if I put in a argument.

Seems like there’s nothing posted about this, so here’s the solution, in case anybody needs it:

$CI =& get_instance();
$db = $CI->load->database("access", true);
$query = $db->get("groups");

Note the semantic differences between the two. I would have much appreciated it if my call to $ci->load->database() triggered some kind of CI error, since it does not, in fact, work correctly.

Tested successfully in v1.5.3. Your mileage will vary.

CodeIgniter: Smarty as a full-fledged template engine

CodeIgniter

I’m a newly converted fan of the CodeIgniter (CI) framework for PHP. I was introduced to it a few weeks back, and there’s been no looking back. PHP has suffered much critique of late here, here and here, but if there’s a star example of beautiful PHP code, here’s it. It helps developers write code better, period.

I really like the many libraries and helpers available, they make the many tiresome things (forms, pagination, input validation) that are rehashed every time a new web application is written a joy, since this is all done for you already. Not that I would recommend someone new to web development to CI, since I’m an advocate of the fact that you must go through some pain to appreciate the beauty in things. But then I digress.

I’m not so keen about the template parsing part though. I had almost expected something like Smarty, but guess I was spoilt. I felt that mixing PHP/HTML syntax was simply… ugly. Tsk, tsk. The user guide indicates that it was an intentional decision to not include a full-blown templating solution, and I think CI suffers for that fact.

So… why not combine CI and Smarty? Note that this is not a CI or Smarty tutorial, if you need help on those things, read the manual! :) According to CI convention, I’ve put the Smarty source code into the libraries folder. Since there are quite a number files, I put it in a subfolder “smarty”, so the path to Smarty is:

system/application/libraries/smarty/Smarty.class.php

Now, we need to extend the Smarty (we’ll call it smarty_library), the code which we stored as:

system/application/libraries/smarty_library.php

There are plenty of Smarty configurations to play around with, but we’ll stick to just two (template_dir and compile_dir). Using absolute paths help prevent those pesky “template not found” errors.

Smarty();

		// absolute path prevents 'template not found' errors
		$this->template_dir = '/path/to/CodeIgniter/system/application/views/'; // use CI's views folder
		$this->compile_dir = '/path/to/CodeIgniter/system/cache/'; //use CI's cache folder -- chmod 777 cache required

		// URL helper required
		$this->assign('site_url', site_url()); // so we can get the full path to CI easily
	}
} // END class smarty_library
?>

Now that this is done, you can put the library load call in your CI application as:

$this->load->library('smarty_library', 'smarty');

Access your Smarty object at:

$this->smarty->assign('foo', $foo);

Please drop comments! I’d love to hear from other like-minded developers! :)