Learn from your fellow PHP developers with our PHP blogs, or help share the knowledge you've gained by writing your own.
composer create-project laravel/laravel --prefer-dist tiny_blog
cd tiny_blog
public function up()
{
Schema::create('blogs', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('category');
$table->string('title');
$table->text('description');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('blogs');
}
php artisan migrate
php artisan make:auth
php artisan serve
http://127.0.0.1:8000
php artisan make:controller BlogController
php artisan make:model Blog
Route::get('blog/create','BlogController@createBlog');
/create/blog/ will be url route that land on Blog Controller's createBlog method using get method.public function createBlog()
{
return view('blog.create');
}
@extends('layouts.app')
@section('content')
<div class="container">
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div><br />
@endif
<div class="row">
<form method="post" action="{{url('blog/create')}}">
<div class="form-group">
<input type="hidden" value="{{csrf_token()}}" name="_token" />
<label for="title">Title:</label>
<input type="text" class="form-control" name="title"/>
</div>
<div class="form-group">
<label for="title">Category/Tags:</label>
<input type="text" class="form-control" name="category"/>
</div>
<div class="form-group">
<label for="description">Description:</label>
<textarea cols="10" rows="10" class="form-control" name="description"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
@endsection
Route::post('blog/create','BlogController@saveBlog');
public function saveBlog(Request $request)
{
$blog = new Blog();
$this->validate($request, [
'title'=>'required',
'category'=>'required',
'description'=> 'required'
]);
$blog->createBlog($request->all());
return redirect('blog/index')->with('success', 'New blog has been created successfully :)'); }
use App\Blog;
Model(app/Blog.php)
, but in actual it is not there:$blog->createBlog($data);
public function createBlog($data)
{
$this->user_id = auth()->user()->id;
$this->title = $data['title'];
$this->description = $data['description'];
$this->category = $data['category'];
$this->save();
return 1;
}
Route::get('blog/index','BlogController@showAllBlogs');
public function showAllBlogs()
{
$blogs = Blog::where('user_id', auth()->user()->id)->get();
return view('blog.index',compact('blogs'));
}
@extends('layouts.app')
@section('content')
<div class="container">
@if(\Session::has('success'))
<div class="alert alert-success">
{{\Session::get('success')}}
</div>
@endif
<a type="button" href="{{url('blog/create')}}" class="btn btn-primary">Add New Blog</a>
<br>
<table class="table table-striped">
<thead>
<tr>
<td>ID</td>
<td>Title</td>
<td>Category</td>
<td>Description</td>
<td colspan="2">Action</td>
</tr>
</thead>
<tbody>
@foreach($blogs as $blog)
<tr>
<td>{{$blog->id}}</td>
<td>{{$blog->title}}</td>
<td>{{$blog->category}}</td>
<td>{{$blog->description}}</td>
<td>Edit</td>
<td>Delete</td>
</tr>
@endforeach
</tbody>
</table>
<div>
@endsection
public function __construct()
{
$this->middleware('auth');
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Blog;
class BlogController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function createBlog()
{
return view('blog/create');
}
public function saveBlog(Request $request)
{
$blog = new Blog();
$this->validate($request, [
'title'=>'required',
'category'=>'required',
'description'=> 'required'
]);
$blog->createBlog($request->all());
return redirect('blog/index')->with('success', 'New blog has been created successfully :)');
}
public function showAllBlogs()
{
$blogs = Blog::where('user_id', auth()->user()->id)->get();
return view('blog.index',compact('blogs'));
}
}
$key = ftok(__FILE__, 'A');
$queue = msg_get_queue($key);
msg_send($queue, 1, 'message, type 1');
msg_send($queue, 2, 'message, type 2');
msg_send($queue, 3, 'message, type 3');
msg_send($queue, 1, 'message, type 1');
echo "send 4 messages
";
queue-receive.php$key = ftok('queue-send.php', 'A');
$queue = msg_get_queue($key);
for ($i = 1; $i <= 3; $i++) {
echo "type: {$i}
";
while ( msg_receive($queue, $i, $msgtype, 4096, $message, false, MSG_IPC_NOWAIT) ) {
echo "type: {$i}, msgtype: {$msgtype}, message: {$message}
";
}
}
u% php queue-send.php
send 4 messages
u% php queue-receive.php
type: 1
type: 1, msgtype: 1, message: s:15:"message, type 1";
type: 1, msgtype: 1, message: s:15:"message, type 1";
type: 2
type: 2, msgtype: 2, message: s:15:"message, type 2";
type: 3
type: 3, msgtype: 3, message: s:15:"message, type 3";
while (msg_receive($queue, $i, $msgtype, 4096, $message, false, MSG_IPC_NOWAIT)) {
$key = ftok('queue-send.php', 'A');
$queue = msg_get_queue($key);
while ( msg_receive($queue, 0, $msgtype, 4096, $message) ) {
echo "msgtype: {$msgtype}, message: {$message}
";
}
$pid = pcntl_fork();
$key = ftok('queue-send.php', 'A');
$queue = msg_get_queue($key);
if ($pid == -1) {
exit;
} elseif ($pid) {
exit;
} else {
while ( msg_receive($queue, 0, $msgtype, 4096, $message) ) {
echo "msgtype: {$msgtype}, message: {$message}
";
}
}
posix_setsid();
$id = ftok(__FILE__, 'A');
$shmId = shm_attach($id);
$var = 1;
if (shm_has_var($shmId, $var)) {
$data = (array) shm_get_var($shmId, $var);
} else {
$data = array();
}
$data[time()] = file_get_contents(__FILE__);
shm_put_var($shmId, $var, $data);
$id = ftok(__DIR__ . '/shared-memory-write-base.php', 'A');
$shmId = shm_attach($id);
$var = 1;
if (shm_has_var($shmId, $var)) {
$data = (array) shm_get_var($shmId, $var);
} else {
$data = array();
}
foreach ($data as $key => $value) {
$path = "/tmp/$key.php";
file_put_contents($path, $value);
echo $path . PHP_EOL;
}
$id = ftok(__FILE__, 'A');
$semId = sem_get($id);
sem_acquire($semId);
$data = file_get_contents(__DIR__.'/06050396.JPG', FILE_BINARY);
$shmId = shm_attach($id, strlen($data)+4096);
$var = 1;
if (shm_has_var($shmId, $var)) {
$data = shm_get_var($shmId, $var);
$filename = '/tmp/' . time();
file_put_contents($filename, $data, FILE_BINARY);
shm_remove($shmId);
} else {
shm_put_var($shmId, $var, $data);
}
sem_release($semId);
umask(0);
$pid = pcntl_fork();
if ($pid < 0) {
print('fork failed');
exit 1;
}
if ($pid > 0) { echo "daemon process started
";
exit;
}
$sid = posix_setsid();
if ($sid < 0) {
exit 2;
}
chdir('/');
file_put_contents($pidFilename, getmypid() );
run_process();
ob_start();
var_dump($some_object);
$content = ob_get_clean();
fwrite($fd_log, $content);
ini_set('error_log', $logDir.'/error.log');
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen($logDir.'/application.log', 'ab');
$STDERR = fopen($logDir.'/application.error.log', 'ab');
function sig_handler($signo)
{
global $fd_log;
switch ($signo) {
case SIGTERM:
fclose($fd_log); unlink($pidfile); exit;
break;
case SIGHUP:
init_data(); break;
default:
}
}
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");
$base = event_base_new();
$event = event_new();
$errno = 0;
$errstr = '';
$socket = stream_socket_server("tcp://$IP:$port", $errno, $errstr);
stream_set_blocking($socket, 0);
event_set($event, $socket, EV_READ | EV_PERSIST, 'onAccept', $base);
function onRead($buffer, $id)
{
while($read = event_buffer_read($buffer, 256)) {
var_dump($read);
}
}
function onError($buffer, $error, $id)
{
global $id, $buffers, $ctx_connections;
event_buffer_disable($buffers[$id], EV_READ | EV_WRITE);
event_buffer_free($buffers[$id]);
fclose($ctx_connections[$id]);
unset($buffers[$id], $ctx_connections[$id]);
}
$event2 = event_new();
$tmpfile = tmpfile();
event_set($event2, $tmpfile, 0, 'onTimer', $interval);
$res = event_base_set($event2, $base);
event_add($event2, 1000000 * $interval);
function onTimer($tmpfile, $flag, $interval)
{
$global $base, $event2;
if ($event2) {
event_delete($event2);
event_free($event2);
}
call_user_function(‘process_data’,$args);
$event2 = event_new();
event_set($event2, $tmpfile, 0, 'onTimer', $interval);
$res = event_base_set($event2, $base);
event_add($event2, 1000000 * $interval);
}
event_delete($event);
event_free($event);
event_base_free($base);
event_base_set($event, $base);
event_add($event);
function onAccept($socket, $flag, $base) {
global $id, $buffers, $ctx_connections;
$id++;
$connection = stream_socket_accept($socket);
stream_set_blocking($connection, 0);
$buffer = event_buffer_new($connection, 'onRead', NULL, 'onError', $id);
event_buffer_base_set($buffer, $base);
event_buffer_timeout_set($buffer, 30, 30);
event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff); event_buffer_priority_set($buffer, 10); event_buffer_enable($buffer, EV_READ | EV_PERSIST); $ctx_connections[$id] = $connection;
$buffers[$id] = $buffer;
}
#! /bin/sh
#
$appdir = /usr/share/myapp/app.php
$parms = --master –proc=8 --daemon
export $appdir
export $parms
if [ ! -x appdir ]; then
exit 1
fi
if [ -x /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
fi
RETVAL=0
start () {
echo "Starting app"
daemon /usr/bin/php $appdir $parms
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/mydaemon
echo
return $RETVAL
}
stop () {
echo -n "Stopping $prog: "
killproc /usr/bin/fetchmail
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mydaemon
echo
return $RETVAL
}
case in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status /usr/bin/mydaemon
;;
*)
echo "Usage:
php {start|stop|restart|status}"
;;
RETVAL=$?
exit $RETVAL
#php app.phar
myDaemon version 0.1 Debug
usage:
--daemon – run as daemon
--debug – run in debug mode
--settings – print settings
--nofork – not run child processes
--check – check dependency modules
--master – run as master
--proc=[8] – run child processes
Me: Is that really important that the tables are MyISAM? It's 2018, you know.. There are dozens of queries in queue waiting for table-level locks.
R**: Are they MyISAM? Really?
Me: Yes.. Any objection against converting them to InnoDB? With the current state of the website, with all those tons of Gateway Timeouts, it's not going to make it worse if I do it right now..
Me: Nah, it didn't help a lot.. But, looking at the SHOW PROCESSLIST output, I see something weird. What, do you think, this query does? SELECT LAST_INSERT_ID() FROM images?
R**: ehh... Gets you the last AUTO_INCREMENT id from images table?
Me: Let's play another good news bad news joke.. Good news: you're right, it gets you the last AUTO_INCREMENT id. Bad news: it's not for table, it's for the session. Worse news: this query gets you the last AUTO_INCREMENT id and does it exactly as many times as there are rows in the images table. how many are there?
R**: about 8mln. #@%&! It's sending 8mln rows on every image upload, through the network!
Me: Bingo! 8mln rows, with one and the same integer value in all of them.
R**: Ouch... Aaaand... Before today, it was not an issue. Because the database was on the same server as the application..
Me: Exactly, it used the loopback interface, and now it's using ehternet, which, apparently, doesn't have a super good bandwidth. We don't have a gigabit channel between servers, do we?
R**: No, it's 100 Mbit
Me: Are you fixing the query, BTW?
R**: yeah, man, deploying it...
class IntArray {
private $values = [];
public function add(int $value) {
$this->values[] = $value;
}
}
Then, whenever you need an array of integers, you may write something like this:class BatchProcessor
{
private $ids;
public function __construct(IntArray $ids) {
$this->ids = $ids;
}
}
Not bad. You'll need a class per type, though, and that may seem a bit of an overkill for such a simple task. Luckily, same result can be achieved differently, but with the same level of confidence in every value type:class BatchProcessor
{
private $ids;
public function __construct(int ...$ids) {
$this->ids = $ids; }
}
Voila - no need for extra class! This approach uses the PHP 7's type hinting for scalar types, in conjunction with Variable length argument lists available since PHP 5.6. In fact, variable-length argument lists have been around since probably the very first version of the language, but in 5.6 they were revisited and got some nice syntactic sugar in form of "...", so you declare and call them as easy as this:function func(...$args){...}
$args = [1, 2, 3];
func(...$args);
The approach can work with any type-hinting available in PHP, and I hope you find it somewhat useful! Comment, discuss share and ask questions - I'll be around.