How to add Respond Json function in OPENX Without plugin

1.add folder in {documnet_root}/www/{yourname}/

ex. adserver/json/

2.add php file ex.api.php

3.add content like this


//xid param from your url like {yourdoamin}/www/json/api.php?xid=10
//xid eq zoneid
//set your AD like banner type


$_GET['zoneid'] =$_GET['xid'];




// Require the initialisation file
require_once '../../init-delivery.php';

// Required files
require_once MAX_PATH . '/lib/max/Delivery/adSelect.php';
require_once MAX_PATH . '/lib/max/Delivery/flash.php';

// No Caching
MAX_commonSetNoCacheHeaders();

//Register any script specific input variables
MAX_commonRegisterGlobalsArray(array('refresh', 'resize', 'rewrite', 'n'));

// Initialise any afr.php specific variables
if (!isset($rewrite))   $rewrite = 1;
if (!isset($refresh))   $refresh = 0;
if (!isset($resize))    $resize = 0;
 
// Get the banner

$banner = MAX_adSelect($what, $campaignid, $target, $source, $withtext, $charset, $context, true, $ct0, $loc, $referer);
// Send cookie if needed
if (!empty($n)) {
    if (!empty($banner['html'])) {
        // Send bannerid headers
        $cookie = array();
        $cookie[$conf['var']['adId']] = $banner['bannerid'];
        // Send zoneid headers
        if ($zoneid != 0) {
            $cookie[$conf['var']['zoneId']] = $zoneid;
        }
        // Send source headers
        if (!empty($source)) {
            $cookie[$conf['var']['channel']] = $source;
        }
        // Set the cookie
        MAX_cookieAdd($conf['var']['vars'] . "[$n]", json_encode($cookie, JSON_UNESCAPED_SLASHES));
    } else {
        MAX_cookieUnset($conf['var']['vars'] . "[$n]");
    }
}

MAX_cookieFlush();

MAX_commonSendContentTypeHeader('text/html', $charset);

// Rewrite targets in HTML code to make sure they are
// local to the parent and not local to the iframe
if (isset($rewrite) && $rewrite == 1) {
    $banner['html'] = preg_replace('#target\s*=\s*([\'"])_parent\1#i', "target='_top'", $banner['html']);
    $banner['html'] = preg_replace('#target\s*=\s*([\'"])_self\1#i', "target='_parent'", $banner['html']);
}

// Build HTML
$outputHtml = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>\n";
$outputHtml .= "<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n";
$outputHtml .= "<head>\n";
$outputHtml .= "<title>".(!empty($banner['alt']) ? $banner['alt'] : 'Advertisement')."</title>\n";

// Include the FlashObject script if required
if (isset($banner['contenttype']) && $banner['contenttype'] == 'swf') {
    $outputHtml .= MAX_flashGetFlashObjectExternal();
}

// Add refresh meta tag if $refresh is set and numeric
if (isset($refresh) && is_numeric($refresh) && $refresh > 0) {
    $dest = MAX_commonGetDeliveryUrl($conf['file']['frame']).'?'.$_SERVER['QUERY_STRING'];
    parse_str($_SERVER['QUERY_STRING'], $qs);
    $dest .= (!array_key_exists('loc', $qs)) ? "&loc=" . urlencode($loc) : '';

    $refresh = (int)$refresh;
    // JS needs to be escaped twice: the setTimeout argument is evaluated at runtime
    $jsDest = addcslashes(addcslashes($dest, "\0..\37\"\\"), "'\\");
    $htmlDest = htmlspecialchars($dest, ENT_QUOTES);

    // Try to use JS location.replace since browsers deal with this and history much better than meta-refresh
    $outputHtml .= "
    <script type='text/javascript'><!--// <![CDATA[
        setTimeout('window.location.replace(\"{$jsDest}\")', " . ($refresh * 1000) . ");
    // ]]> --></script><noscript><meta http-equiv='refresh' content='".$refresh.";url={$htmlDest}'></noscript>
    ";
}

if (isset($resize) && $resize == 1) {
    // If no banner found, use 0 as width and height
    $bannerWidth = empty($banner['width']) ? 0 : $banner['width'];
    $bannerHeight = empty($banner['height']) ? 0 : $banner['height'];

    $outputHtml .= "<script type='text/javascript'>\n";
    $outputHtml .= "<!--// <![CDATA[ \n";
    $outputHtml .= "\tfunction MAX_adjustframe(frame) {\n";
    $outputHtml .= "\t\tif (document.all) {\n";
    $outputHtml .= "\t\t\tparent.document.all[frame.name].width = ".$bannerWidth.";\n";
    $outputHtml .= "\t\t\tparent.document.all[frame.name].height = ".$bannerHeight.";\n";
    $outputHtml .= "\t\t}\n";
    $outputHtml .= "\t\telse if (document.getElementById) {\n";
    $outputHtml .= "\t\t\tparent.document.getElementById(frame.name).width = ".$bannerWidth.";\n";
    $outputHtml .= "\t\t\tparent.document.getElementById(frame.name).height = ".$bannerHeight.";\n";
    $outputHtml .= "\t\t}\n";
    $outputHtml .= "\t}\n";
    $outputHtml .= "// ]]> -->\n";
    $outputHtml .= "</script>\n";
}

$outputHtml .= "<style type='text/css'>\n";
$outputHtml .= "body {margin:0; height:100%; background-color:transparent; width:100%; text-align:center;}\n";
$outputHtml .= "</style>\n";
$outputHtml .= "</head>\n";

$jsonArr['html'] =  ($banner['html']);

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials true');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept,token,Access-Token');
header('Access-Control-Max-Age: 1728000');
header("Content-type: application/json; charset=utf-8");

echo json_encode($jsonArr);
exit;

Laravel 5/7 Redis的分庫設定

在此之前,有一些預備工作要做的

Redis driver

按照官方建議 用phpredis

redis是可以設定他在他一個db內的,例如我的全站設定檔是在db3,我的客戶暫存是在db1,預設是在db0

當我在連線設定沒有指定,預設會跑到db0,那為什麼要分呢?因為redis是沒有辦法做特徵全部刪除的,例如他無法做到刪除key name 為abc_開頭的資料 ,我必須要知道keyname的完整名稱,這樣如果我的網站站存檔要全部更新的話,就很麻煩,你可能還要跑資料庫迴圈把相關資料叫出來,不能爽快的flushdb…,但如果你今天把資料分門別類,那你就可以對db3下達flush指令,這樣效率會高一點,而且你要改小部分資料的時候,在沒有看code的情況下,透過工具也比較好找,例如我只要改一個設定檔案,我只要透過Medis之類的GUI工具就可以修改,不需要半夜打電話叫工程師起床尿尿 叫他看一下他設定的key name是什麼

在config/database.php 內 記錄了redis的設定


'redis' => [

        'client' => env('REDIS_CLIENT', 'phpredis'),

        'options' => [
            'cluster' => env('REDIS_CLUSTER', 'redis'),
            'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
        ],

        'default' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_DB', '0'),
        ],
        'db1' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' =>'1',
        ],
        'db2' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' =>'2',
        ],
        'db3' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' =>'3',
        ],
        'cache' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_CACHE_DB', '1'),
        ],

    ],
這裡的陣列中,我設定了幾個索引名稱,這個在後來的連線上會用到

設定連線




        $setobj = Redis::connection('db3');

        $rf=[];
        if($setobj->exists($key)){
            $rf['exist']=1;
            $rf['rs']=$setobj->get($key);

        }else{
            $rf['exist']=0;

        }

對應到上面的索引設定,我就是從db3裡面撈取資料,而不是從預設的db0撈取,這樣不同的程式甚至是不同的功能,就可以共用同一個redis,而不會互相影響到

laravel 5 增加一組route group 設定

我今天要增加一組route controller與 route檔案
名字叫ajax
要到 class RouteServiceProvider 修改
1.增加namespace
protected $cust_namespace = ‘App\Http\Controllers\ajax’;
2.
去map route增加一組設定
$this->mapAjaxRoutes();
3.增加method mapAjaxRoutes

protected function mapAjaxRoutes()
{
Route::prefix(‘ajax’)
->middleware(‘ajax’)
->namespace($this->cust_namespace)
->group(base_path(‘routes/ajax.php’));
}

 

完整設定會是這樣

<?php 
namespace App\Providers; 
use Illuminate\Support\Facades\Route; 
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; 
class RouteServiceProvider extends ServiceProvider { 
/** * This namespace is applied to your controller routes. * * In addition, it is set as the URL generator's root namespace. * * @var string */ 
    protected $namespace = 'App\Http\Controllers'; 
    protected $cust_namespace = 'App\Http\Controllers\ajax'; /** * Define your route model bindings, pattern filters, etc. * * @return void */ 
    
     public function boot() { // parent::boot(); } 
    
     /** * Define the routes for the application. * * @return void */ 
    public function map() { $this->mapApiRoutes();
        $this->mapAjaxRoutes();
        $this->mapWebRoutes();

        //
    }

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
             ->namespace($this->namespace)
             ->group(base_path('routes/web.php'));
    }

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
             ->middleware('api')
             ->namespace($this->namespace)
             ->group(base_path('routes/api.php'));
    }
    /**
     * Define the "Ajax" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapAjaxRoutes()
    {
        Route::prefix('ajax')
            ->middleware('ajax')
            ->namespace($this->cust_namespace)
            ->group(base_path('routes/ajax.php'));
    }
}



安裝 php v8js in centos 7

為了完整性 建議手動安裝

1.先安裝工具包

yum groupinstall ‘Development Tools’

2.安裝git  python libglib2.0-dev

3.安裝depot_tools

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

export PATH=`pwd`/depot_tools:”$PATH”

4.下載v8

fetch v8 cd v8

5.設定 GN

tools/dev/v8gen.py -vv x64.release

echo is_component_build = true >> out.gn/x64.release/args.gn

6.編譯

ninja -C out.gn/x64.release/

7.安裝編譯好的檔案

sudo mkdir -p /opt/v8/lib

sudo mkdir -p /opt/v8/include

sudo cp out.gn/x64.release/lib*.so out.gn/x64.release/*_blob.bin /opt/v8/lib/

sudo cp -R include/* /opt/v8/include/

 

9.安裝v8js

git clone https://github.com/phpv8/v8js.git

cd v8js phpize ./configure –with-v8js=/opt/v8

make ; make install

10設定so

vim /etc/php.d/v8js.ini

extension=v8js.so

 

參考文件

 

https://github.com/phpv8/v8js/blob/master/README.Linux.md

 

 

laravel validator note – unique與exists

laravel validator 這兩個功能非常的強大阿~~~

unique >輸入值必須是唯一值

exists >輸入值必須存在

他可以透過orm的方式讀取db資料,然後判斷輸入的值是否存在於資料表中,根本是大神級的好用阿

範例
id值必須存在否則輸出錯誤
exists:table名稱,欄位名稱

$info['id']=10; 
$validator = Validator::make(
            $info,
            [
                'id' => 'exists:table_name,id',
               
            ]
        );
if ($validator->fails()) {
            return response()->json(['status'=>422,'message'=>'Validate Error','errors'=>$validator->errors()],422,[],JSON_UNESCAPED_UNICODE);

}

範例
帳號是否存在,存在則輸出錯誤
unique :table名稱,欄位名稱

$info['username']='Mike'; 
$validator = Validator::make(
            $info,
            [
                'id' => 'unique :table_name,username',
               
            ]
        );
if ($validator->fails()) {
            return response()->json(['status'=>422,'message'=>'Validate Error','errors'=>$validator->errors()],422,[],JSON_UNESCAPED_UNICODE);

        }

laravel validator note – regex rule

laravel的 Validator是個強大的工具
但是他在用regxp2的時候,會有一個特殊的寫法
他必須是要用陣列
否則會出現
preg_match(): No ending delimiter ‘/’ found

這個是一般的寫法
用|增加RULE

$ruleArr['id']= 'required|numeric|exists:book,id';

這個是REGXP的寫法

$ruleArr['version']=["required","regex:/^(\d+\.)?(\d+\.)?(\*|\d+)$/"];

laravel 清除cache

laravel 幾種cache清除指令

基本 cache
$ php artisan cache:clear

route cache
$ php artisan route:cache

config cache
在新刪修config以後要重新跑一次

$ php artisan config:cache

laravel 5.6 以後廢棄的優化指令,5.4以前通用 ,5.5以後因為走了php 7,這個版本對op-cache有最佳化,所以廢了

$ php artisan optimize

laravel 5.6 passport Unauthenticated

基本上問題在access token

預設安裝的情況下,laravel使用的grant_type是passport
所以在大多數的教學中,他需要先登入後取得access_token, 然後再設定header使用 Authorization: Bearer access_token
BUT
如果你使用的是client_credentials….
你就會拿到UNAUTHENTICATED

需要調整相關的設定
1.app/Http/Kernel.php
增加以下程式
use Laravel\Passport\Http\Middleware\CheckClientCredentials;
protected $routeMiddleware = [
‘client’ => CheckClientCredentials::class,
];

2.修改api route middlerware

Route::get(‘/user’, function(Request $request) {

})->middleware(‘client’);

把middleware改成client即可

判斷special chars

基本上,這邊會有一個需求,就是偵測字串 只要是special char就報錯 不能用過濾後的方式去處理

看了半天,這個方法是我目前為止看到最好的判斷方式

 


$table = get_html_translation_table(HTML_ENTITIES, ENT_COMPAT, 'UTF-8');
$chars = implode('', array_keys($table));

if (preg_match("/[{$chars}]+/", $string) === 1) {
    // special chars in string
}