アナログCPU:5108843109

ゲームと音楽とプログラミング(酒と女とロックンロールのノリで)

('ω') < イザユケエンジニャー

WinSCPでローカルとサーバーのフォルダの移動を同期する

WinSCPは左にローカル側フォルダ、右にサーバー側フォルダが表示されていますが、
デフォルトでは片方でフォルダ遷移してももう片方は動きません。

これを同期させたかったので調べてみた。

  • ログインして、左右のフォルダ階層を合わせる
  • 一旦接続を切る
  • 改めてログイン情報の設定画面を開き、「設定」ボタンを押す
  • 開いたウインドウ内の「環境」>「ディレクトリ」にある「ローカルとリモートのディレクトリ移動を同期する」にチェックを入れて「OK」
  • 設定を保存し再度ログイン

これで同時に動いてくれるようになります。
ただし、片方にしか存在しないフォルダに移動すると、ほとんどの場合同期が解除されてしまいます。
そうなったら最初からやり直し。階層を合わせてから接続を切り、もう一度設定し再ログインです。めんどくさい。

参考
WinSCP でフォルダ同期移動 - パソコンサポートの00H ~社長BLOG~

<追記>

もっと簡単な方法があったorz
f:id:honey8823:20190227100323p:plain

配列をクエリストリングに変換する

連想配列なオブジェクトは、「$.param(オブジェクト)」で簡単にクエリストリング化できます。すげーお手軽。

// listは配列
var list = {
    hoge: 123,
    fuga: 456,
    piyo: 789,
}
// listをクエリストリング化
var querystring = $.param(list);
 
// 表示( hoge=123&fuga=456&piyo=789 となる)
console.log(querystring);

デバッグ用に一時的にログファイル出力するやつ

別に一時的なログでなくとも同じようなもんですが、よく使うので…要するに自分用コピペメモです。


PHPで開発する際、デバッグで変数の中身を知りたいときはvar_dump等でお手軽に画面表示できますが、
諸々の理由で画面には出したくない場合もあります。

  • 稼働中の本番環境で確認したい
  • データが膨大なのでブラウザには表示したくない
  • ajaxで呼び出すのでそもそもvar_dump等ではダメ

など。

そういう場合はログファイルに放り込めばよいので、その書き方を。

<?
$dat = ... ; // 中身を確認したい変数

// >>> デバッグ用 >>>>>>>>>>
$logtext  = "================================\n";
$logtext .= date("Y-m-d H:i:s") . "\n";
$logtext .= var_export($dat, true) . "\n\n";
file_put_contents("ログファイルのフルパス", $logtext, FILE_APPEND);
// <<<<<<<<<<<<<<<<<<<<<<<<<

これで、日時と変数の内容がログファイルに追加されていきます。

var_exportは変数だけを渡すと画面に表示する関数ですが、第2引数にtrueを渡すことで表示は行わず、戻り値に文字列が得られるようになります。
PHP: var_export - Manual

また、file_put_contentsの第3引数のFILE_APPENDはログファイルに追記するための定数です。
追記ではなく上書きしてしまいたい場合は省略すればOK。
PHP: file_put_contents - Manual

アップロードされた画像をDBに保存する

作る機会があったのでメモ。
フォームのタイプとか、DBではなくファイルとして保存するとか、そういうアレンジは適当に。

手順

ざっくり分けると以下のような感じ。

  • 画像のアップロードフォームを作る
  • アップロードされた画像を加工する(リサイズなど)
  • 加工した画像をbase64化する
  • base64化したデータをDBに保存する
続きを読む

Surface Pro 4 を交換に出してみた

2016年2月に購入して以来、便利に使い倒していたSurfaceさんですが

今年に入ってから、時々画面がちらつくようになりました。

軽い時は「ちょっと一瞬ノイズが走ったように見えた」という感じ、
重い時は「画面全体がものすごいブレブレで表示内容の認識が困難」という感じ。

応急処置としては、本体を冷やすと直ることが多いです。

更新プログラムで解決できない問題だそうで、2018年5月頃から無償交換が始まりました。
https://support.microsoft.com/ja-jp/help/4230448/surface-pro-4-screen-flicker
Surface Pro 4に画面ちらつきの不具合、マイクロソフトが無償交換へ | マイナビニュース

以下の条件に該当すればリフレッシュ品との交換に応じてくれます。

  • Surface Pro 4を使っていて、ちらつきが発生する
  • 最新の状態にしても解決しない
  • 購入から3年以内である → 3年経過している場合は有償でなら対応してくれるようです

交換プロセスをざっくり書くと、以下のような感じ。

  • 問い合わせて交換受付の処理をしてもらう
  • 本体をMicrosoftに送付する
  • 5~8営業日程度で交換品が返送されてくる

「交換なのでデータなどをバックアップしておく必要がある」「数日間は手元から消える」というのがめんどくさいポイントですね。
症状も軽いし別にいっか…な人は冷やしながら使うのもアリだと思います。
わたしは開発作業してると症状がめちゃくちゃ重くなり本当に困るので今回交換に出すことにしました。
(レイヤー何十枚の高解像度絵を描いてても平気なことが多いのに、Apache起動してしばらく使うだけで、表示されているものが認識できないレベルに酷くなっていた…)

交換に応じてもらい、返ってきたものもしばらく使ってみたので、詳しい手順を残しておきます。
問い合わせしたのが2018年10月29日なのでその時点の情報ということで。

準備

問い合わせ前に、以下の準備を済ませておくとスムーズです。

  • シリアルIDを控えておく
    • 設定→システム→バージョン情報→システム情報 で確認可能
    • これさえ控えておけば、問い合わせ時は本体が手元になくてもOK
  • Microsoftアカウントのメールを確認できる状態にしておく
    • 問い合わせ時の通話中、本人確認のためにメールを受信して内容を確認する必要が出てきます
  • メモが取れるようにしておく(紙でもスマホでもPCでもいいので)

問い合わせ開始

完了までは20分程度見たほうがよいです。

電話で問い合わせます。番号は「 0120-54-2244 」。
自動の音声案内に従って操作…するのですが、真面目に聞いているとたどり着けませんでした。
問い合わせ内容によって番号を入力する形式で、「1→4→1」でOKです。

「ここに空メールするとサポート情報送るよ」とか「surfaceの交換はネットでも受け付けてるよ」とか言われますが、全部無視。
釣られてちょっと見てみたところ、今回のようなイレギュラーには対応していないようです。
最後の選択肢も、「購入から1年未満なら1、それ以上なら…」という質問ですが、問答無用で1でOKでした。
そうでなければ「有料の案内」か「フォーラムへの誘導」の二択になります。

イレギュラーにも対応してほしいっていうか、リコールみたいなもんなんだから専用の窓口用意していいレベルだと思うんだけど…。

手続きの流れ

オペレーターさんにつながるまでが一苦労でだいぶキレそうになりましたが(さすがMicrosoft)、
オペレーターさんはとても親切で分かりやすい説明をしてくれました(さすがMicrosoft)。

通話がつながったら
Surface Pro 4を使っていて、画面のちらつきが発生するので交換していただきたいのですが…」
で通じます。

順番はうろ覚えですがだいたい以下のような内容。

  • 名前と電話番号を聞かれる
  • 対象SurfaceのシリアルIDを伝え、交換対象であるかを判断してもらう
  • 本人確認(Microsoftアカウント宛にメールが来るので、本文中の確認番号を伝える)
  • 交換に際してのいろいろな説明を受ける
  • 受付番号を教えてもらう
  • 本体の送付方法や送付先を教えてもらう
  • Officeの再インストール方法を教えてもらう

受ける説明の多くは、電話後にもらえるメールに記載されています。
ただ、メールは100%届く保証があるわけではないので、最低限受付番号はメモしておきましょう。

受けた説明のまとめ

  • 本体(※1)を指定住所(※2)へゆうパック着払いで送ってね
    • 品名に受付番号を記載してね
  • 到着後5営業日後くらいに交換品を発送するよ
  • 交換だからデータは消えるよ
  • Officeも再インストールが必要だよ(※3)

※1
電話で明言されなかったような気がしますが、本体のみ。
キーボードやペンなどは不要です。
(もし誤って送った場合も返してくれるかとは思います。わたしはうっかりmicroSDカードを入れっぱなしにしていましたがご丁寧な梱包で返送いただきました)
いらない段ボールや緩衝材で梱包してやります。
これも明言されなかった気がしますが、壊れ物であることを書いておいた方がいいかも。
(例えば品名に「タブレット端末」追記するとか)

※2
メモしてね!と言われますがメールに記載されています。
 -------------------------------------------------------------
 〒143-0001 東京都大田区東海1-3-6 プロロジスパーク東京大田 3F
 Quantium Solutions(株) 気付 マイクロソフト サービス センター
 (電話番号欄には問い合わせの「0120-54-2244」でOK)
 -------------------------------------------------------------

※3
これは人によるかも。
自分の場合はMicrosoftアカウントにOfficeも紐づいていたので、
マイページからインストールするだけ、と言われました。
ちなみにインストール用に紹介された短縮URLは「 aka.ms/mya 」です。

返送された交換品を受け取ったら完了

10/29に申込み、11/7頃には受け取れる状態でした。
これをセットアップし、バックアップしておいたデータを入れなおして交換完了です。
元の端末で重たかった操作もいろいろ試してみましたが、画面のちらつきは発生せず。快適になりました。

後日談

運が悪かった。

回数を指定して文字列置換

文字列を置換するのはふつうstr_replace関数を使用しますが
PHP: str_replace - Manual
これは文中の特定文字をすべて置換することしかできません。

最初の1回だけ置換したいような場合はpreg_replaceで回数指定することができます。
第1~第3引数はいつも通りに「置換前のパターン」「置換後の文字列」「置換対象の文字列」で、
第4引数に回数を入れておくだけでOK。

<?php
// 置換前の文字列
$str  = "abcabcabc";

// 1回だけ置換
$str1 = preg_replace("/a/", "A", $str, 1); // Abcabcabc

// 2回だけ置換
$str2 = preg_replace("/a/", "A", $str, 2); // AbcAbcabc

先読み後読みと併用することで、「あるパターンより前の特定文字を1回だけ置換」「○文字目より後の特定文字を1回だけ置換」なんてことも。

<?php
// 置換前の文字列
$str  = "abcabcabc";

// あるパターンより前にある特定文字を1回だけ置換
// ※この例では存在しないパターンとなるので実際は置換されない
$str3 = preg_replace("/a(?=bcd)/", "A", $str, 1) // abcabcabc

// ○文字目より後の特定文字を1回だけ置換
$str4 = preg_replace("/(?<=.{3})a/", "A", $str, 1) // abcAbcabc

(先読み後読みについてはこちら)
正規表現の先読み・後読み - アナログCPU:5108843109

さらに、preg_replaceのパターンは配列でも指定できるので、配列指定かつ回数指定する場合の挙動はどうなってるんだろう…? と思い試してみました。

<?php
$str  = "abcabcabc";
var_dump( preg_replace(array("/a/", "/b/"), array("A", "B"), $str, 2) ); // ABcABcabc

$str = "aaabbbccc";
var_dump( preg_replace(array("/a/", "/b/"), array("A", "B"), $str, 2) ); // AAaBBbccc
var_dump( preg_replace(array("/a/", "/b/"), "X", $str, 2) ); // XXaXXbccc

配列で複数パターンを指定した場合、パターンごとに回数が適用されるようですね。

蛇足な雑談

いや、今回ハマったのが、「後読みには文字数が可変になるようなパターンを指定できない」というものでして、
具体的には、HTMLエスケープされたある文字列について、特定のタグのみエスケープを解除したいという事案でした。

例えばdivタグのみエスケープ解除するとして、

&lt;div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;div class="hoge"&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;/div&gt;

<div>
&lt;p&gt;
&lt;/p&gt;
</div>
<div class="hoge">
&lt;p&gt;
&lt;/p&gt;
</div>

としたい、ということですね。

これを一発

<?php
$str = " ... "; //(省略。エスケープ後文字列)

$pattern_before = array(
    "/&lt;(?=\/?div[\s\/>&])/",
    "/(?<=(<|\/)div[^&]*)&gt;/",
);
$pattern_after = array(
    "<",
    ">",
);
$str = preg_replace($pattern_before, $pattern_after, $str);

こんな感じで置換してしまいたかったのですが、後読みの方がうまくいかず。

仕方ないので、今回調べた内容を使って以下のように実装しました。

<?php
$str = " ... "; //(省略。エスケープ後文字列)

while (true)
{
    // divタグの位置を探す、なければ終了
    // 「&lt;(<)」と「div」の間はスラッシュのみ許容、「div」と「&gt;(>)」の間は&以外を許容
    if (!preg_match($"/&lt;\/?div[\s\/>&]/", $str, $matches, PREG_OFFSET_CAPTURE))
    {
        break;
    }
    
    // divタグが存在する場合:
    // 見つかった位置以降について、最初に見つかった&lt;と&gt;を置換するパターンを生成
    $pattern_before = array(
        "/(?<=.{" . $matches[0][1] . "})&lt;/",
        "/(?<=.{" . $matches[0][1] . "})&gt;/",
    );
    $pattern_after = array(
        "<",
        ">",
    );
    
    // 置換した文字列で$strを上書き
    $str = preg_replace(array(, ), array("<", ">"), $str, 1);
}

もっと美しい実装があるかもしれません。
あまり厳密ではないですしなんかダサい気もします。
(今回実装していたのはCMSなので厳密さは一応こんなもんで良いのですが)

ファイル名を適当にナンバリングするVBS

Windowsにて、ひとつのフォルダの中にあるファイル名を「001.***」「002.***」「003.***」…という感じで自動でナンバリングしたくて9年ほど前に作ったやつ。
その後ずっと使ってて謎の愛着のあるVBSなんですが、最近ファイル管理の命名規則変えて使わなくなったのでお蔵入りする代わりに貼っておく。

準備

  • 対象フォルダに「name.ini」というテキストファイルを用意
    • 中身は「001」とだけ入力
  • VBSファイル(コードは後述)はデスクトップでもなんでも好きなところに置いておく

使い方

  • ナンバリングしたいファイルを対象フォルダに入れる
  • ナンバリングしたい順に、VBSファイルの上にドラッグ&ドロップする

VBSのコード

無駄に長い。

続きを読む

Smartyでよく使うあれこれ

メモ。

値を表示する

基本(そのまま表示)
{$hoge}

ちなみに配列の中身を表示する場合はこんな感じでドットでつないで辿ることができます。

{$hoge.fuga}
HTMLエスケープして表示する
{$hoge|escape:'html'}
改行文字をbrタグに変換して表示する
{$hoge|nl2br}
HTMLエスケープ&改行文字をbrタグに変換して表示する
{$hoge|escape:'html'|nl2br}

逆に書くと想定通りに動きません。
たぶんbrタグに変換したやつをHTMLエスケープすることになるからだと思う。

コメントアウトする

{*
ここはコメントアウトされます
HTMLでのコメントアウト <!-- --> と違ってソースにも表示されません。
*}

他のテンプレートファイルをincludeする

{include file='header.tpl'}

ヘッダ部分など、共通化しているものを呼び出すときなど。

繰り返し処理・分岐処理

foreach
{foreach from=$hoge key=k item=v}
  <!-- 配列$hogeについて繰り返し処理 -->
  <p>{$v.id} {$v.name}</p>
{/foreach}

forもあるけどsmarty内ではまず使わないので必要になったらググる

if
{if $hoge != ""}
  <!-- $hogeが空でないとき表示 -->
  {$hoge}
{/if}

条件式の書き方はたぶんPHPと同じ。

日付フォーマット

{* 現在日時 → 任意のフォーマット *}
{$smarty.now|date_format}

{* PHPで解釈可能な日付文字列 → 任意のフォーマット *}
{strtotime($datetime)|date_format:"%Y-%m-%d %H:%M:%S"}

フォーマットに使えるやつ
date_format | Smarty

フォーマット文字列の中に日本語があるとエラーになるときもある(よく調べてない)
PHPの関数も使えるので(後述)以下なら動くけど、ちょっとどうかと思う

{date("Y年m月d日 H時i分s秒", strtotime($datetime))}

PHPの関数もまあまあ使える

やりすぎると「PHPでやれ」感出てくるけど。
だいたいifの条件式に使いがちなのでサンプルコードはifとの合わせ技。

書いてたら無限に出てきそうなので、自分の中でかなり頻出なやつを。
次点でcountとかarray_columnとかも使う。

isset

PHP側で初期化しておくのがめんどくさいときに。

{if isset($hoge)} $hogeに値が渡されている {/if}
is_array

PHP側で空配列に初期化しておくのがめんどくさいときに。

{if is_array($hoge)} $hogeは配列 {/if}
in_array

わざわざPHP側で表示用の判定のためだけの値を作りたくないときに。

{if in_array($val, $array)} 配列に含まれている {/if}

あんまり関係ないメモ

プラグインを作るという手もある。
[PHP] Smartyプラグインの作り方 – 端くれプログラマの備忘録

windowsでシンボリックリンクを作る

たまに作る機会があると毎回ぐぐってるのでメモ。

<追記>
ボケてきたのか、「シンボリックリンク」という単語がなかなか出てこなくてぐぐることすらできなくて困ってたので検索用にメモする。
シンボリックリンクとはショートカットと似て非なる、windowsでは影の薄いアレ。
</追記>

ななどら外伝2人旅シリーズ #6:サムライ×ハッカー(2020)

セブンスドラゴン2020でサムライとハッカーの2人旅。


キャラメイク

  • 「グリシーナ」ハッカー / オタクスタイル♀ / CV:ゆかな
  • 「アツタ」サムライ / スチューデントスタイル♂ / CV:中村悠一

よその13班から借りました。

f:id:honey8823:20180928104906j:plain:w400

0章(Lv1~)

  • D1:Lv--で撃破(8ターン)
  • D2:Lv--で撃破(13ターン)

レベルメモするの忘れた。でもまあたどり着いた時のレベルそのままで一発クリア。

1章(Lv6~)

  • ドラゴハンマード:Lv7、TAKE2で撃破(12ターン)
  • ウォークライ:Lv13、TAKE7で撃破(23ターン)

ドラゴハンマードではLv5→Lv7、ウォークライではLv10→Lv13と上げました。
意外とキツかった。

スキル
 グリシーナ:LF2、ATK2、DEF3、リジェネ1、サバゲ1
 アツタ:LF2、袈裟斬り4、練気2、赤火2

二人旅では意外と効いてくるLIFEボーナスを押さえておきつつ。

1.5章(Lv13~)

  • ラクモ本部改修①
  • スモウドラグ:Lv13、TAKE2で撃破(18ターン)
  • グラナロドン:Lv17、TAKE3で撃破(8ターン)

スモウドラグは初見hageたものの、いけそうだったので消費アイテム揃え直して再戦で突破。
グラナロドンはLv15でたどり着きましたがかなりキツかったので少しLv上げしてスキルも増やしてからなんとか撃破。

スキルについては、
グリシーナさんは支援スキルを強化し、アツタくんは居合コースを目指しはじめました。

2章(Lv17~)

  • ジゴワット:Lv23、TAKE2で撃破(13ターン)
  • SKY:Lv23で撃破(9ターン)

ジゴワットは、TAKE1で氷が弱点なのを忘れてて長期化した結果ジリ貧でアウト。
SKYは今回もネコから狙い、ネコは5ターン。

3章(Lv23~)

  • デストロイドラグ:Lv24、TAKE1で撃破(7ターン)
  • ロア・ア・ルア:Lv28、TAKE2で撃破(18ターン)

いつも苦戦しがちのデストロイドラグはまさかの一発クリア。
ロア・ア・ルアはLv27&Lv28で到達、一度失敗したので二人ともLv28に揃えてから挑戦でクリア。
というかTAKE2はスキルと装備揃えるの忘れたまま突っ込んだのに勝ててしまった…。

4章(Lv28~)

  • ラクモ本部改修②
  • SKY:Lv34、TAKE3で撃破(18ターン)
  • トリニトロ:Lv35で撃破(16ターン)

前回のハッカー2人旅ではめちゃくちゃ苦戦した国分寺ですが、敵の弱点ははっきりしているのでサムライがいるとむしろボーナスステージ。
SKYはネコ→ダイゴ→タケハヤの順に倒しました。

5章(Lv35~)

  • スリーピーホロウ:Lv40で撃破(11ターン)

一発クリア。これもボーナスステージですね。

6章(Lv41~)

  • ザ・スカヴァー(尾):Lv44で撃破(7ターン)
  • ザ・スカヴァー(胴):Lv44で撃破(9ターン)
  • ザ・スカヴァー(頭):Lv44で撃破(22ターン)

なんなくクリア。

7章(Lv45~)

  • ラクモ本部改修③
  • ゼロ・ブルー:Lv50、TAKE9で撃破(24ターン)

久々に苦戦。
Lv49で到達したものの、勝てそうで勝てないことが続き4回チャレンジ、Lv一つ上げてから5回チャレンジで。

X章(Lv50~)

  • クリミナルドラグ:Lv56、TAKE4で撃破(--ターン)
  • ミヅチ:Lv58で撃破(25ターン)
  • すべてのドラゴンを狩りつくした!
  • ニアラ:Lv64、TAKE7で撃破(36+9ターン)

クリミナルドラグがちょっとキツかった。
ちょっとミスると唐突に全滅する。
Lv55とLv56で2回ずつ挑戦してなんとか突破。

ミヅチはノーミス。特に危ないところもなく。

ニアラは…どうだったっけ。
メモ忘れてたんですが、確かLv62でたどり着いたような。

おしまい

前回はハッカーハッカーでしたが、片方をサムライに変えるだけですごい安定感…。